Skip to main content
Clarified variable names
Source Link
John Burger
  • 1.9k
  • 1
  • 13
  • 23

This is the perennial problem of C programmers: how to return something created inside the function. You have threefour choices (each with their own problems):

Note that both of thesethe above two solutions have the same two problems:
a. You can't calculate the length and then use it - it has to be created at the maximum possible size.
b. There is only one array. That means that if the same function is called again, it will overwrite the results from last time - use it before you lose it!
b. You can't calculate the length and then use it - it has to be created at the maximum possible size.

  1. You can make the caller pass in the array to fill. Rather than return the array, have another parameter that is the array to fill - and for safety's sake, get them to pass in the size of the array too. You'll have to check that and return an error if it's not big enough - or do something else sensible.
  2. You can allocate the memory from a different area that where it's currently being allocated from. That area is called the "heap" - it's just a heap o' memory that you can request chunks from - and don't forget to give it back!
free(decodedStringreturnedString);
char *decodedString = new char[decodedLength];
 
...
// And later...
delete [] decodedString;returnedString;

This is the perennial problem of C programmers: how to return something created inside the function. You have three choices (each with their own problems):

Note that both of these solutions have two problems:
a. You can't calculate the length and then use it - it has to be created at the maximum possible size.
b. There is only one array. That means that if the same function is called again, it will overwrite the results from last time - use it before you lose it!

  1. You can allocate the memory from a different area that where it's currently being allocated from. That area is called the "heap" - it's just a heap o' memory that you can request chunks from - and don't forget to give it back!
free(decodedString);
char *decodedString = new char[decodedLength];
 
...

delete [] decodedString;

This is the perennial problem of C programmers: how to return something created inside the function. You have four choices (each with their own problems):

Note that the above two solutions have the same two problems:
a. There is only one array. That means that if the same function is called again, it will overwrite the results from last time - use it before you lose it!
b. You can't calculate the length and then use it - it has to be created at the maximum possible size.

  1. You can make the caller pass in the array to fill. Rather than return the array, have another parameter that is the array to fill - and for safety's sake, get them to pass in the size of the array too. You'll have to check that and return an error if it's not big enough - or do something else sensible.
  2. You can allocate the memory from a different area that where it's currently being allocated from. That area is called the "heap" - it's just a heap o' memory that you can request chunks from - and don't forget to give it back!
free(returnedString);
char *decodedString = new char[decodedLength];
...
// And later...
delete [] returnedString;
Source Link
John Burger
  • 1.9k
  • 1
  • 13
  • 23

Your variable decodedString[] is created inside the function, used inside the function - and destroyed inside the function before it returns.

See how your function decodeImage() returns a char *? That's a pointer to a character array, not the whole array - and you can't return a whole array. The pointer is successfully returned all right - but what it is pointing to is overwritten by future calls and future created variables.

This is the perennial problem of C programmers: how to return something created inside the function. You have three choices (each with their own problems):

  1. You can make the variable global - put it outside the function and let anyone access it. Then you don't even need to return the string - it's already accessible.

  2. You can make decodedString a permanent part of the function by making it static:

     static char decodedString[64];
    

Note that both of these solutions have two problems:
a. You can't calculate the length and then use it - it has to be created at the maximum possible size.
b. There is only one array. That means that if the same function is called again, it will overwrite the results from last time - use it before you lose it!

  1. You can allocate the memory from a different area that where it's currently being allocated from. That area is called the "heap" - it's just a heap o' memory that you can request chunks from - and don't forget to give it back!

To request memory from the heap, you call the function malloc and pass in the number of bytes that you want. It returns a pointer to that lump of memory:

char *decodedString = (char *)malloc(decodedLength);

Note that malloc doesn't know what you're going to use the memory for, so you have to tell the compiler - that's what the (char *) before the call to malloc does.

But if you use malloc, at some stage you must give the memory back with a call to free:

free(decodedString);

The function that did the malloc doesn't have to be the function that frees it - any function can, as long as some function does! Otherwise you'll run out of heap.

Another thing that you must NOT do is call free on the same block twice: that will corrupt the heap, since it will mark the same block on the heap twice, and hand it back out twice later, corrupting the data when it is used again.

EDIT

There's a C++ version of malloc / free called new / delete. You use them similarly:

char *decodedString = new char[decodedLength];

...

delete [] decodedString;

It looks and behaves similarly to malloc and free, without the ugly (char *) type-cast. Note that since an array was allocated with the new, you need to call the array version of delete by adding the [] as shown.