LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   C - Segfault during malloc. Something to do with how I'm using the pointers.... (https://www.linuxquestions.org/questions/programming-9/c-segfault-during-malloc-something-to-do-with-how-im-using-the-pointers-797372/)

golmschenk 03-23-2010 02:21 PM

C - Segfault during malloc. Something to do with how I'm using the pointers....
 
So the place where I'm having a problem is here:
Code:

typedef struct {
void **Mem_Chunk;
char *Mem_Chunk_Used;
int MAX_CHUNKS;
int Last_Chunk;
} mm_t;

int mm_init (mm_t *MM, int hm, int sz) {
        int i;
        char *tmpchar;
        void *tmp;
        fprintf(stderr,"Here!\n");
        tmpchar = (char*)malloc(hm*sizeof(char));
        fprintf(stderr,"Here 2!\n");
        MM->Mem_Chunk_Used = tmpchar;
        fprintf(stderr,"Here 3!\n");
        void *tmp = malloc(hm*sz);
        MM->Mem_Chunk = tmp;
        ......

"Here 2!" prints so I'm getting the problem at MM->Mem_Chunk_Used = tmpchar;. I'm sure it's just I'm doing something wrong with my pointers but I'm not sure what it is. Anyone see my problem? Thanks a bunch!

Sergei Steshenko 03-23-2010 02:29 PM

Quote:

Originally Posted by golmschenk (Post 3909404)
So the place where I'm having a problem is here:
Code:

typedef struct {
void **Mem_Chunk;
char *Mem_Chunk_Used;
int MAX_CHUNKS;
int Last_Chunk;
} mm_t;

int mm_init (mm_t *MM, int hm, int sz) {
        int i;
        char *tmpchar;
        void *tmp;
        fprintf(stderr,"Here!\n");
        tmpchar = (char*)malloc(hm*sizeof(char));
        fprintf(stderr,"Here 2!\n");
        MM->Mem_Chunk_Used = tmpchar;
        fprintf(stderr,"Here 3!\n");
        void *tmp = malloc(hm*sz);
        MM->Mem_Chunk = tmp;
        ......

"Here 2!" prints so I'm getting the problem at MM->Mem_Chunk_Used = tmpchar;. I'm sure it's just I'm doing something wrong with my pointers but I'm not sure what it is. Anyone see my problem? Thanks a bunch!

You probably haven't allocated memory or allocated not enough memory for 'MM'.

You haven't published here full code showing what is happening before you call 'mm_init'.

golmschenk 03-23-2010 03:07 PM

This is up to mm_init:
Code:

int main (int argc, char *argv[]){
mm_t *Mem_Man;
//timer
struct timeval time_start, time_end;
int j,i;
void *tmp;
void *Mem_Stuff[1000];
    /* start timer */
mm_init(Mem_Man,1000,64);
.....

Any idea? Thanks a bunch.

golmschenk 03-23-2010 03:09 PM

Wait, so do I have to allocate *Mem_Man with memory somehow first?

jiml8 03-23-2010 03:25 PM

*Mem_Man is allocated. It is a pointer to a structure of type mm_t.

What you have not done is allocate the memory for that structure, and assign the address of that memory to the pointer.

Mem_Man = malloc(sizeof(mm_t))

golmschenk 03-23-2010 03:32 PM

So just to make sure I know what you're saying, even though I'm using malloc for the parts of Mem_Man later, to be able to do that I first have to malloc for Mem_Man itself? Thanks a bunch by the way.

jiml8 03-23-2010 03:41 PM

Pointers have to point to something, or else they point to garbage.

Your later mallocs are to fill pointers in your structure. The memory is NOT put there, it is put wherever the OS wants it, and your pointer points to it.

You have to allocate memory to hold the structure that has the pointers. Then you have to have a pointer to point to that memory.

So, yes. You have to allocate memory for your structure.

Now, had you done this:

Code:

int main (int argc, char *argv[]){
mm_t Mem_Man;

then your entire structure would have been allocated for you on the stack.

In that case, to access an element of the structure, you'd use the syntax Mem_Man.Mem_Chunk_Used.

To point to the structure so you could pass the pointer to a subroutine, you'd use the syntax &Mem_Man.

Sergei Steshenko 03-23-2010 03:52 PM

Quote:

Originally Posted by golmschenk (Post 3909514)
So just to make sure I know what you're saying, even though I'm using malloc for the parts of Mem_Man later, to be able to do that I first have to malloc for Mem_Man itself? Thanks a bunch by the way.

A pointer is just an "address"/address. I.e. if a municipality gave your future house a street address, you don't have a house yet - you have to build it. Suppose also you don't even have a lot to build on - instead you have a forest. So when you cut out part of the forest and get in such a manner a piece of (flat) land, than you have actually allocated the land for building.

In this analogy system memory allocator is the entity cutting out the trees in the forest. It also makes accounting, i.e. it won't allow somebody else to cut out the same piece of forest and build on it. Also, the system memory allocator knows how much forest to be cut out at all exists - any single person can't have more forest cut out then total forest area.

The house with its walls, floors, stairs, etc. is you structure - the allocator doesn't care about the internals, it cares about total area of you lot.

johnsfine 03-23-2010 05:10 PM

Quote:

Originally Posted by golmschenk (Post 3909479)
Code:

int main (int argc, char *argv[]){
mm_t *Mem_Man;
...
mm_init(Mem_Man,1000,64);


I think you already understand why the above is wrong.

The usual way to code that would be

Code:

int main (int argc, char *argv[]){
mm_t Mem_Man;
...
mm_init(&Mem_Man,1000,64);

The mm_t object in main() makes more sense as just an object, rather than a pointer to an object. Then you don't need to worry about allocating and deallocating it. It lasts just as long as main() lasts.

Then, when you pass it to a function such as mm_init, you pass the address of the object, rather than the value of a pointer. Note the & I used above.

This method does require the extra & each place you pass it to a function and means main() accesses the members differently than every other function, for example:

In main
Mem_Man.Mem_Chunk
vs. in any other function
MM->Mem_Chunk

If those syntax issues bother you, you could make both a pointer and an object

Code:

int main (int argc, char *argv[]){
mm_t Mem_Man_actual;
mm_t *Mem_Man = &Mem_Man_actual;
...
mm_init(Mem_Man,1000,64);

So the & isn't needed on each function call.

If the desired duration of the object were not the same as the duration of main(), that is the case in which it is best to use malloc:

Code:

int main (int argc, char *argv[]){
mm_t *Mem_Man = malloc(sizeof(mm_t));
...
mm_init(Mem_Man,1000,64);


Sergei Steshenko 03-23-2010 06:23 PM

Quote:

Originally Posted by johnsfine (Post 3909608)
...
If the desired duration of the object were not the same as the duration of main(), that is the case in which it is best to use malloc:

Code:

int main (int argc, char *argv[]){
mm_t *Mem_Man = malloc(sizeof(mm_t));
...
mm_init(Mem_Man,1000,64);


Well, it's the case when size also matters. If an object is big, it better be allocated on heap (i.e. using 'malloc') regardless of the duration of the enclosing scope. I.e. stack is more "expensive" than heap.

The beauty of stack allocation is that it takes no time and typically doesn't need operations similar to 'free'.

golmschenk 03-23-2010 09:55 PM

Good good good. Thanks all again!


All times are GMT -5. The time now is 09:53 PM.