ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm a fairly newbie C programmer, self-taught, and have just started working seriously on a project I've been dabbling with for some years. At the moment I have a vary basic ecosystem simulator that is almost ready to be released as version 0.0.1 but I'm getting some baffling run-time crashes. Looking into this I suspect that there is something in the area pointers that I don't quite get and as the program uses such concepts as function pointers and arrays of structures then there is probably some sort of memory leak, or something. Could someone please help fill me in on how memory allocation works in C. I had read several books on the subject but none go into enough detail. For example, as far as I know the following short program should work fine and it compiles without any problems but when I run it I get a "Segmentation fault". Why? What's wrong with this program?
Code:
#include <stdio.h>
#include <stdlib.h>
// Set up a coordinate structure
struct Coords
{
int X;
int Y;
};
// Set up an array of structures (???)
struct Coords **CoordArray;
int main()
{
// Initialises the first element of the array
CoordArray[0] = malloc (sizeof (struct Coords));
return 0;
}
The main program is a Linux port of a version I wrote several years ago in Dos using a Borland command-line compiler that did work so I know the general idea is correct, but I just cannot get the Linux version to stop crashing. Ideas anyone?
The program which i hav written below compiles as well as run successfully. Try to see the difference.
#include <stdio.h>
#include <stdlib.h>
// Set up a coordinate structure
struct Coords
{
int X;
int Y;
};
// Set up an array of structures (???)
struct Coords **CoordArray;
int main()
{
// Initialises the first element of the array
CoordArray = malloc (sizeof (struct Coords)*10);
CoordArray[0] = malloc (sizeof (struct Coords));
return 0;
}
See tht CoordArray is a pointer to pointers of struct Coords type elements so before accessing CoordArray[0] u must allocate memory to it.
Thanks shivaligupta, that's probably what's been missing from my program. Time for another strip-down and re-design! Next question, the main program uses an array of structures called EntityType. There are three main entity types at present which use function pointers within the structure to handle the same messages differently (OOP-style polymorphism in C! Genius!), grass, rabbits and foxes. Foxes eat Rabbits eat Grass. Of course beacuse of this they can all die and spawn depending on whether they eat a lot or get eaten so I need a sort of dynamic structure array where each element of the array has to be able to create and destroy the structure it's pointing to at at will. The main loop then, when searching through the array and getting the movements of each, will check if the element contains an entity or not, preferbly using something like
Code:
if (EntityArray[i] == NULL) { ... ask for the entitys' next move ... }
else { ... check the next element} ...
However, expanding on the original code snippet, the following program compiles and runs OK but doesn't work as expected:
Code:
#include <stdio.h>
#include <stdlib.h>
// Set up a coordinate structure
struct Coords
{
int X;
int Y;
};
// Set up an array of structures (!!!)
struct Coords **CoordArray;
int main()
{
// Sets the size of the array, eventually this should be defined
// by the user either at runtime or through a config file
int ArraySize = 10;
// Initialises the first element of the array
CoordArray = malloc (sizeof (struct Coords)*10);
CoordArray[0] = malloc (sizeof (struct Coords));
CoordArray[0]->X = 4;
CoordArray[0]->Y = 5:
printf ("CoordArray[0] = (%i, %i).\n", CoordArray[0]->X,CoordArray[0]->Y);
free (CoordArray[0])
if (CoordArray[0]) == NULL)
printf ("It worked!\n");
else
printf ("It didn't work.\n");
printf ("CoordArray[0] = (%i, %i).\n", CoordArray[0]->X, CoordArray[0]->Y);
return 0;
}
When I compile and run this I get the following output:
CoordArray[0] = (4, 5).
It didn't work.
CoordArray[0]= (0, 5).
First of all why does the condition (CoordArray[0]) == NULL) not work? And secondly I would expect the line
to give a segmentation error as I'm accessing a pointer after it has been free()d. Why doesn't free() assign the pointer the null value (or more to the point what does free() actually do as all it seems to do is set the first value of the struct to zero, Y is still 5). Also putting the line
Code:
CoordArray[0]) == NULL
after the free() line only gives me the compiler warning message "statement with no effect" and running it makes no difference. In summary (!) how do I ensure that when my program is checking through the array that it doesn't re-use an entity that has already died without using some stupid widget like
Code:
if (EntityArray[i]->IsDead == 1)
?
By the way, thanks a lot for getting back to me so fast, I wasn't expecting a reply so soon
I tried that but all I got was a compiler warning message saying "malloc3.c warning: statement with no effect" and the if (CoordArray == NULL) statement still didn't work. Is there another way of setting the value to NULL?
[recieves e-mail notification - goes to website - reads posting]
sleepisforwimps: (under breath) Yeah, yeah whatever.
[looks at source file]
sleepisforwimps: (reading) CoordArray[0] == NULL;
[turns bright red]
sleepisforwimps: Where did that *#~%^|* second equals sign come from?
[alters source file - compiles - runs]
sleepisforwimps: Oh, it works
[looks at posting again]
sleepisforwimps: (reading) Your not doing CoordArray[0] == NULL; outside an if-statement, are you?
[turns room upside down looking for hidden camera]
To be continued...
Alright, ta. Time for a strip-down and redesign methinks. I'll be back when I get my next "Segmentation fault" error
Yeah, post again if you have further problem! I'm sooo stuck on my own projects right now that I don't mind helping others so they, at least, see some progess in their projects.
Alright next question. The following code works correctly as expected:
Code:
#include <stdio.h>
#include <stdlib.h>
// Set up a coordinate structure
struct Coords
{
int X;
int Y;
};
// Set up an array of structures
struct Coords **CoordArray;
// Function to allocate memory
void AllocMem (struct Coords *NewCoord);
int main()
{
// Sets the size of the array, eventually this should be defined
// by the user either at runtime or through a config file
int ArraySize = 10;
// Initialises the array
CoordArray = malloc (sizeof (struct Coords) * ArraySize);
// Initialises the first element of the array
CoordArray[0] = malloc (sizeof (struct Coords));
//AllocMem (CoordArray[0]);
if (CoordArray[0] != NULL)
printf ("It worked!\n");
else
printf ("It didn't work.\n");
return 0;
}
void AllocMem (struct Coords *NewCoord)
{
NewCoord = malloc (sizeof (struct Coords);
}
This compiles fine and the output is "It worked!" OK, all fine. Now lets do a quick change and switch around some comment markers so that we get the following program:
Code:
#include <stdio.h>
#include <stdlib.h>
// Set up a coordinate structure
struct Coords
{
int X;
int Y;
};
// Set up an array of structures
struct Coords **CoordArray;
// Function to allocate memory
void AllocMem (struct Coords *NewCoord);
int main()
{
// Sets the size of the array, eventually this should be defined
// by the user either at runtime or through a config file
int ArraySize = 10;
// Initialises the array
CoordArray = malloc (sizeof (struct Coords) * ArraySize);
// Initialises the first element of the array
//CoordArray[0] = malloc (sizeof (struct Coords));
AllocMem (CoordArray[0]);
if (CoordArray[0]) != NULL)
printf ("It worked!\n");
else
printf ("It didn't work.\n");
return 0;
}
void AllocMem (struct Coords *NewCoord)
{
NewCoord = malloc (sizeof (struct Coords);
}
The only difference here is that the malloc() statement is handled by the AllocMem() function and not in main(). CoordArray[0] is passed as a pointer to the AllocMem() function which performs the malloc() action on it. However, although the program compiles fine the output now becomes "It didn't work." meaning that the malloc() statement somehow doesn't work when handled by a function. The only explanation I can think of to explain this is that there is some problem with the scope of the malloc() function when handled in the AllocMem() function but surely this would not be an issue when pointers are used? If the AllocMem() function is rewritten as:
In other words the AllocMem() function first sets the element but once the flow returns to main() then it returns to NULL. Why and how do I get around that?
The reason I'm asking by the way is that I'm trying to code a structure that uses function pointers to allow different instances of the structure to respond differently to the same occurence. The ability to create and destroy an element of a structure array within a function is an important design feature, if I don't find a sensible and clean way around this problem it will make the design of the program quite different.
If you run that program it will *always* print NULL. Why? Well, the pointer itself is passed by value. If you print the address of the ptr in main() and in set_pointer(), you will see that they are different You can print address with:
Thanks a lot, I tried your code and it worked great. Of course, it's meant another completely new re-design this design is a LOT cleaner than any of my previous attempts. I have to admit that I don't understand why it works but I can kind of think with it and my program hasn't given me any "Segmentation faults" yet (admittedly it doesn't do a whole lot yet) and there are several other designs issues I was having problems with that I'm starting to think with and can probably find a solution for now. My last few designs were quite ugly as my attempts to emulate the Grand Design (TM) kept getting "Segmentation faults" so I kept putting in more and more hacks in order to make it fit but now it's looking a little closer to the Grand Design (TM) than it's ever been!
In brief, thank you, you've made at least one bedroom coder happy today (and even more allergic to sleep than ever)
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.