1

I am having problems with an array which i want to re-use in my program. I need to change the size dynamically and clear it. But unfortunately the resizing does not work.

uint8_t * readBuffer; // Create array pointer

readBuffer = (uint8_t *) malloc(4); // Mem. alloc. 4bytes
memset(readBuffer, 0, sizeof(readBuffer); // Reset array
// Do stuff
free(readBuffer) // Release mem. block
....
readBuffer = (uint8_t *) malloc(1) // Mem. alloc. 1byte
memset(readBuffer, 0, sizeof(readBuffer); // Reset array
// Do stuff
free(readBuffer) // Release mem. block

At the the resizing step the length of my array is still the former (4).

Am i using free all wrong?

Further more is there much more efficient alternatives to memset for clearing?

Thanks in advance.

JavaCake
  • 4,075
  • 14
  • 62
  • 125
  • How do you know it's 4? Also, why not `realloc`? – Pubby May 02 '12 at 11:51
  • I check with `sizeof(readBuffer)` – JavaCake May 02 '12 at 11:51
  • `sizeof(readBuffer)` doesn't return the size of the memory allocated by `malloc` , it just returns the number of bytes required to store the pointer value. – Naveen May 02 '12 at 11:52
  • @Naveen, is there an alternative to finding the length? – JavaCake May 02 '12 at 11:53
  • @Pubby, the compiler complains that its not been initialized when using `realloc(readBuffer, 1)`. How should i init the pointer again? – JavaCake May 02 '12 at 11:54
  • @JavaCake: No standard API to do that, you need to keep track of it yourself. BTW, if you can use C++, consider using `std::vector`. – Naveen May 02 '12 at 11:54
  • 5
    this has been said over and over but I'll still repeat it (as this is tagged C++): use std::vector and your problems are solved. And if you really must acces the raw memory, use &(*vector.begin()) – stijn May 02 '12 at 11:55
  • @Naveen, that should not be a problem. I will avoid sizeof. – JavaCake May 02 '12 at 11:55
  • @stijn, i assume that vector works somewhat like in Java? – JavaCake May 02 '12 at 11:56
  • @stijn, if you have experience with std::vector can you explain the efficiency compared to the method im using. Also in means of clearing arrays (max. 1MB). – JavaCake May 02 '12 at 11:58
  • `std::vector` performs as well as or better than what you are trying to do. More importantly it correctly manages its resources so you don't have to. Have you considered reading [a good C++ book](http://stackoverflow.com/questions/388242) – Blastfurnace May 02 '12 at 12:13
  • yes it's like in Java/C#/whatever and I have no idea about the efficiency; only that I've used vector everywhere in a lot of different programs and never had performance issues. – stijn May 02 '12 at 12:14
  • @Blastfurnace, i have a good C++ book laying around, which i perhaps should look further into concerning vectors. – JavaCake May 02 '12 at 12:17
  • @stijn, well it depends on which device your running on to make an assumption on how the performance is. Im primarily coding embedded systems, so its quite essential that it does not eat up memory. I will try it out and see how efficient it works. – JavaCake May 02 '12 at 12:18
  • I've used it on embedded systems as well. I do have to say I ususally preallocate a lot there though, on a deterministic system you do not really want to do huge reallocations, no matter if you use malloc or vector – stijn May 02 '12 at 12:25
  • @stijn, that sounds interesting. It just reminded me that i used `std::vector` when i was working in OpenCV 2years ago. Perhaps i should look into it in the weekend and refactor my code. It will look less messy. – JavaCake May 02 '12 at 12:27

3 Answers3

5

Size of a pointer (e.g. readBuffer) is always same (here 4 bytes) for any data type. You need to rather store the size given inside the malloc into a temporary and then use memset():

uint size = 4;
readBuffer = (uint8_t *) malloc(size); // Mem. alloc. 4bytes
memset(readBuffer, 0, size); // Reset array

Moreover argument to malloc() is in bytes, so malloc(1) means ideally 1 byte. If you are using C++ then use new:

readBuffer = new uint8_t[N];  // 'N' is number of elements of "uint8_t"

Edit:

In C++, std::vector provides this facility with much ease:

std::vector<uint8_n> readBuffer(N, 0);

Here you are allocating 'N' elements for readBuffer and initializing them to 0.
Whenever you want to add elements, you can use push_back() method. For bigger chunks you may also explore resize() or reserve() methods.

iammilind
  • 68,093
  • 33
  • 169
  • 336
1

At the the resizing step the length of my array is still the former (4).

The problem is that sizeof(readBuffer) returns the size of the pointer, and not the amount of memory allocated by malloc(). If you want to track the latter, you have to do it yourself.

Am i using free all wrong?

No, you're using free() correctly.

is there much more efficient alternatives to memset for clearing?

I doubt there's a much more efficient way. You could trying using calloc(), which is just like malloc() but zero-initializes the memory for you.

Lastly, it is a good idea to check whether malloc() has returned NULL, which it could do if there's not enough memory to satisfy the request.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
1
uint8_t * readBuffer; // Create array pointer

readBuffer = (uint8_t *) malloc(4); // Mem. alloc. 4bytes
memset(readBuffer, 0, sizeof(readBuffer); // Reset array
// Do stuff
free(readBuffer) // Release mem. block
....
readBuffer = (uint8_t *) malloc(1) // Mem. alloc. 1byte
memset(readBuffer, 0, sizeof(readBuffer); // Reset array
// Do stuff
free(readBuffer) // Release mem. block

The casting of the malloc isn't necessary. Also, readBuffer doesn't have a size, what you want to do is sizeof(Uint8_t) * 4. This gives your the right size.

And instead of malloc, you should use realloc, since you want to re-allocate an excisting pointer of memory blocks. The return value of this points to the new memory block, or NULL, if no memory on the heap is available. New code:

uint8_t * readBuffer; // Create array pointer

readBuffer = malloc(4); // Mem. alloc. 4bytes
memset(readBuffer, 0, (sizeof(uint8_t) * 4)); // Reset array
// Do stuff
free(readBuffer) // Release mem. block
....
uint8_t * temp = realloc(readBuffer, 1); // Mem. alloc. 1byte
if(temp != NULL) readBuffer = temp; //Check if their was enough room to allocate memory
memset(readBuffer, 0, (sizeof(uint8_t) * 4)); // Reset array
// Do stuff
free(readBuffer) // Release mem. block
Davey
  • 447
  • 2
  • 7
  • 27