Home > Software design >  do I need to allocate space for pointer as well as space for memory area whose address will be kept
do I need to allocate space for pointer as well as space for memory area whose address will be kept

Time:11-03

I have this code

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

    int i=1;
    char **m=malloc(sizeof(char *)*i);
    printf("%zu\n",sizeof *m);
    m[0]=malloc(strlen("hello") 1);
    strcpy(m[0],"hello");
    printf("%s\n", m[0]);
    i=2;
    m=(char **)realloc(m,sizeof (char *)*i);
    m[1]=malloc(strlen("hi") 1);
    strcpy(m[1],"hi");
    printf("%s %s \n",m[0],m[1] );
    // TODO: write proper cleanup code just for good habits.
    return 0;
}

this is how I am allocating pointer char **m 8 byte single char pointer

    int i=1;
    char **m=malloc(sizeof(char *)*i);

and this is how I am allocating area of space whose address will be kept in m[0]

m[0]=malloc(strlen("hello") 1);
strcpy(m[0],"hello");
printf("%s\n", m[0]);

I like to know is this normally how its done. I mean allocating space for pointer and then allocating space in memory that the pointer will hold.

Does m[0]=malloc(strlen("hello") 1); is same as this *(m 0)=malloc(strlen("hello") 1); and does this m[1]=malloc(strlen("hi") 1); this *(m 1)=malloc(strlen("hi") 1);

And I am increasing pointer to pointer numbers like this in allocation m=(char **)realloc(m,sizeof (char *)*i); before m[1]=malloc(strlen("hi") 1);

is there anything wrong with above code. I seen similar code on this Dynamic memory/realloc string array

can anyone please explain with this statement char **m=malloc(sizeof(char *)*i); I am allocating 8 byte single pointer of type char but with this statement m=(char **)realloc(m,sizeof (char *)*i); why I am not getting stack smaching detected error. How exactly realloc works. can anyone give me the link of realloc function or explain a bit on this please

CodePudding user response:

I like to know is this normally how its done. I mean allocating space for pointer and then allocating space in memory that the pointer will hold.

It depends on what you are trying to achieve. If you wish to allocate an unspecified amount of strings with individual lengths, then your code is pretty much the correct way to do it.

If you wish to have a fixed amount of strings with individual lengths, you could just do char* arr [n]; and then only malloc each arr[i].

Or if you wish to have a fixed amount of strings with a fixed maximum length, you could use a 2D array of characters, char arr [x][y];, and no malloc at all.

Does m[0]=malloc(strlen("hello") 1); is same as this *(m 0)=malloc(strlen("hello") 1);

Yes, m[0] is 100% equivalent to *((m) (0)). See Do pointers support "array style indexing"?

is there anything wrong with above code

Not really, except stylistic and performance issues. It could optionally be rewritten like this:

char** m = malloc(sizeof(*m) * i); // subjective style change
m[0]=malloc(sizeof("hello"));      // compile-time calculation, better performance

why I am not getting stack smaching detected error

Why would you get that? The only thing stored on the stack here is the char** itself. The rest is stored on the heap.

How exactly realloc works. can anyone give me the link of realloc function or explain a bit on this please

It works pretty much as you've used it, though pedantically you should not store the result in the same pointer as the one passed, in case realloc fails and you wish to continue using the old data. That's a very minor remark though, since in case realloc fails, it either means that you made an unrealistic request for memory, or that the RAM on your system is toast and you will unlikely be able to continue execution anyway.

The canonical documentation for realloc would be the C standard C17 7.22.3.5:

#include <stdlib.h>
void *realloc(void *ptr, size_t size);

The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values.

If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size. Otherwise, if ptr does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to the free or realloc function, the behavior is undefined. If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.

Returns
The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated.

Notably there is no guarantee that the returned pointer always has the same value as the old pointer, so correct use would be:

char* tmp = realloc(arr, size);
if(tmp == NULL)
{
  /* error handling */
}
arr = tmp;

(Where tmp has the same type as arr.)

CodePudding user response:

Your code looks fine to me. Yes, if you are storing an array of strings, and you don't know how many strings will be in the array in advance, then it is perfectly fine to allocate space for an array of pointers with malloc. You also need to somehow get memory for the strings themselves, and it is perfectly fine for each string to be allocated with its own malloc call.

The line you wrote to use realloc is fine; it expands the memory area you've allocated for pointers so that it now has the capacity to hold 2 pointers, instead of just 1. When the realloc function does this, it might need to move the memory allocation to a different address, so that is why you have to overwrite m as you did. There is no stack smashing going on here. Also, please note that pointers are not 8 bytes on every platform; that's why it was wise of you to write sizeof(char *) instead of 8.

To find more documentation about realloc, you can look in the C standard, or the POSIX standard, but perhaps the most appropriate place for this question is the C standard, which documents realloc on page 314.

  •  Tags:  
  • c
  • Related