开发者

Why no "realloc" seems necessary when allocating new element to a char pointer?

开发者 https://www.devze.com 2023-01-16 21:49 出处:网络
I\'m trying to create a pointer to char pointer to which I can easily add new elements (strings). I use malloc to create the first 2 dimensions and realloc when I want to add new items. I wrote code w

I'm trying to create a pointer to char pointer to which I can easily add new elements (strings). I use malloc to create the first 2 dimensions and realloc when I want to add new items. I wrote code with and without realloc and I'm getting the same results. Is this an expected/normal behavior?

With realloc:

    char **p; // create pointer to char pointer
    p = malloc(sizeof(char*) * 2); // allocate 2 dimensions
    p[0] = "ab";
    p[1] = "cd";

    void* resizedP = 开发者_StackOverflow社区(void*)realloc(p, sizeof(char*) * 4); // resize array
    p = (char**)resizedP;
    p[2] = "ef";
    p[3] = "gh";

    printf("%s \n", p[0]); // prints ab
    printf("%s \n", p[1]); // prints cd
    printf("%s \n", p[2]); // prints ef
    printf("%s \n", p[3]); // prints gh

    free(p);

Without realloc:

    char **p;
    p = malloc(sizeof(char*) * 2);

    p[0] = "ab";
    p[1] = "cd";
    p[2] = "ef";
    p[3] = "gh";

    printf("%s \n", p[0]); // prints ab
    printf("%s \n", p[1]); // prints cd
    printf("%s \n", p[2]); // prints ef
    printf("%s \n", p[3]); // prints gh

    free(p);


It is absolutely necessary to call realloc() to resize a memory block obtained by malloc(). You are invoking undefined behavior by accessing beyond the bounds of the memory block that has been allocated to your program.

There might be some important data right after your allocated memory block that your second code snippet will run over. And if the program even attempts to access memory blocks in another process because of an out-of-bounds error, the operating system will complain loudly (resulting in segmentation faults).

There is no guarantee that your second code snippet (without realloc()) won't crash or otherwise fail in the future. It just happened to work this time.


In your case, it may work by coincidence. For example, your C library's malloc() may decide to pad your allocation size by some number which happens to be >= 2*sizeof(void*).

However, in theory, there is nothing to stop a subsequent malloc from returning the bytes that happen to lie at p[2]. There is also nothing to stop malloc from returning a value whereby after the size you requested, the OS hasn't mapped any page into the address space. Therefore you should not rely on this behavior. Don't write to p[2] without allocating the right amount, because that could lead to any of the following:

  • You overwrite a value that some other function has written.
  • Some other function may overwrite you later.
  • You may crash trying to access it.


Try running your second option through valgrind or with the -fstack-protector compiler switch. You might get more information about why In silico's answer is right.


Suppose your p is a bus with space for 20 people.

And you try to put 30 people inside (without enlarging it). Some times it works, if they're not fat ...

In respect to C, that's Undefined Behaviour. Anything can happen. You were unlucky just now and it "worked".

In short: Don't do that!


Whoa don't do that man! There's a reason it works, and it's nothing but trouble.

Firstly, p isn't an array, it's a pointer, you can see this by checking sizeof(p) it will always return either 4 or 8, depending on whether you are running a 32 or 64 bit system.

A pointer refers to a position in memory so if you try to print a pointer, you'll get a memory address, such as 0x0B32D2F1 on a 32-bit machine, When you call one of the *alloc functions, the processor finds a free block of memory of the size you request, and allocates it to your program.

What you doing is accessing and editing memory that hasn't been allocated to you, while being easily possible, nothing stops you from doing it, but it's bad because that memory might be allocated to a different program, and then the user will hate you when you crash his other programs. In short, ALWAYS ALLOCATE THE MEMORY YOU WILL BE USING! ALWAYSS!

Oh yeah, then there's the possibility the processor will allocate that unallocated memory you're using to another program, which will mess with yours.

0

精彩评论

暂无评论...
验证码 换一张
取 消