简体   繁体   中英

C Pointer to Pointer Allocation

I have code that works, however I'm not quite understanding why. I am allocating a pointer with a string, passing that string into a function, and modifying it. I'm confused in that it seems to run fine even if the string entered is far larger than the original string. I expect it to complain about overwriting memory, especially since the original pointer was not MALLOC/CALLOCed.

void changeArray(char *(*anArray)[3]);

Function Declaration

char *testArray[] = { "This is a test", "A Second Test", "A Third Test" };

Pointer declaration & init

    changeArray(&testArray);

Function Call

void changeArray(char *(*anArray)[3]){
char userName[200];
printf("What is your name?:\t");
scanf("%199[^\n]s", userName);
*anArray[0] = userName; }

The Function

    printf("Your name is: %s\n", testArray[0]);

Printing the result in main.

Why is testArray[0] able to accept the new string without reallocating memory for it? Even more baffling is I'm looking at the result under locals and it appears corrupted, but still prints fine.

+       [0] 0x00e2f850 "D`\x3\x1 øâ"    char *

I know it's weird to ask about working code, but I need to make sure I'm understanding what's happening so I can correctly implement/avoid it later.

You're confusing strings and pointers. A 'string' in C is an array of characters in memory, usually referred to by a pointer to the start of the array. So when you declare

char *testArray[] = { "This is a test", "A Second Test", "A Third Test" };

this declares testArray as an a array of 3 pointers, and initializes each pointer to point at a static string (array of characters probably in read-only memory).

In your changeArray function, you have:

char userName[200];
printf("What is your name?:\t");
scanf("%199[^\n]s", userName);
*anArray[0] = userName;

This creates a new local array of characters and fills it in with the user input (presumably their name), and then points the 0th pointer in the array passed by reference as an argument at this local variable. Once this function returns, the stack frame will be freed, leaving the pointer dangling (pointing into the now freed stack frame) so it may seem to work but then seems to change randomly. Accessing a local variable like this after the scope it is in has exited is undefined behavior -- anything might happen.

What you are seeing here is undefined behavior.

You have a local array userName within void changeArray() and you have pointer to it which is valid just within the function, once you return from the function the memory allocated to this local array is freed so accessing this location outside its scope is undefined . You might even see a crash

This is undefined behavior, and it is legal for undefined behavior to work as expected under certain circumstances (and fail miserably under other circumstances).

In your case, you are allocating the userName on the stack within a function. When the function returns, the memory that userName occupies remains intact, usually. But there is absolutely no guarantee for it. The next function call may clobber your string. An asynchronous signal handler might clobber your string as well, which can happen even between the return of the function and the execution of the next line in main() .

Nevertheless, undefined behavior is completely undefined, and your program is perfectly entitled to wipe your harddrive when it is executed. So try to avoid undefined behavior unconditionally.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM