0
//char char **p; declared in .h file
size_t bs = 5;
size_t Size = sizeof(obj);
p = (char**)malloc(bs);
for (size_t i = 0; i < bs;i++){p[i] = (char*)malloc(Size);}

for (size_t j = 0; j < bs-1; j ++){p[j] = &(p[j + 1][0]); }

for (size_t i = 0; i < bs; i++){free(p[i]);}

free(p);

my code stalls up when trying to free the last element of p in the for loop. Anyone what i might be doing wrong?

EDIT: I still have the same problem even when changing it to (char*)malloc(bs sizeof(char *));

this still does not work:

size_t bs = 5;
size_t Size = sizeof(obj);
p = (char**)malloc(bs* sizeof(char *));
for (size_t i = 0; i < bs;i++){p[i] = (char*)malloc(Size);}
for (size_t j = 0; j < bs-1; j ++){p[j] = &(p[j + 1][0]); }
for (size_t i = 0; i < bs; i++){free(p[i]);}
free(p);

using new instead of malloc does not solve the issue either

However this code frees up the memory fine.

size_t bs = 5;
size_t Size = sizeof(obj);
p = (char**)malloc(bs* sizeof(char *));
for (size_t i = 0; i < bs;i++){p[i] = (char*)malloc(Size);}
for (size_t i = 0; i < bs; i++){free(p[i]);}
free(p);

so the problem seem to be something with this piece of code

for(size_t j = 0; j < bs-1; j ++){p[j] = &(p[j + 1][0]); }

I want this to be an implicit linked list, anyone know have an idea what i am doing wrong?

3 Answers3

2

You are not allocating enough space for the pointers. Change to

p = malloc(bs * sizeof(char*));
cup
  • 7,589
  • 4
  • 19
  • 42
  • This is one reason why C++ is better. It would have allocated the proper amount with `new`. – Mark Ransom Jan 24 '14 at 21:29
  • 1
    @Mark: I guess you meant to say "why C++'s `new[]` operator is better"? `malloc` works exactly the same in C++, and C++ allocation functions such as `::operator new()` also require the number of bytes. – Ben Voigt Jan 24 '14 at 21:33
1

At the first malloc, you don´t need 5 byte, but 5 times a pointer.

p = (char**)malloc(bs * sizeof(char *));
deviantfan
  • 11,268
  • 3
  • 32
  • 49
  • okay i changed it to (char**)malloc(bs * sizeof(char *)); its still giving me the same problem. – user3233447 Jan 24 '14 at 21:30
  • 1
    This is true, but *leak* isn't the right word for it. It's actually an overflow, because elements past the end are accessed. – Ben Voigt Jan 24 '14 at 21:30
  • 1
    Technically a leak is when you forget to free something. You've identified the problem but given it the wrong name. – Mark Ransom Jan 24 '14 at 21:30
1

The problem is that you:

  • allocate an array of 5 pointers
  • allocate 5 arrays of characters and store them in that first array
  • move those pointers down in the array, overwriting (and losing) the first pointer and duplicating the last one
  • attempt to free the 5 pointers in the array.

So on this last step, you free a pointer twice (as the last two entries at p[3] and p[4] are the same), causing undefined behavior.

You say you want "an implicit linked list", implying that you're trying to stuff pointers into the objects (rather than into the top level array, as you are doing), in which case you want something like:

for(size_t j = 0; j < bs-1; j ++) { *(char **)p[j] = p[j + 1]); }
*(char **)p[bs-1] = 0;  // null terminate the linked list

this assumes that obj is defined something like:

struct obj {
    struct obj *next;
    // more fields
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226