从静态内存复制字符串到动态内存失败,程序三次输入后崩溃求助
Fixing Your Friend Name Input Crash & Memory Issues
Hey there, let's walk through exactly why your code crashes after three inputs and fix all the underlying issues. Let's start with the problems in your original code, then show a corrected version.
Key Issues in Your Original Code
- You never use the
ppFriendNameparameter:This is the biggest problem! You allocate memory tobyteReALLevery loop, but you never save that pointer to the array passed in viappFriendName. Each loop overwritesbyteReALL, leaving the previous allocations lost (memory leak) and the caller gets nothing. No wonder the program crashes—you're not managing the intended storage at all. - Incorrect malloc size:
strlen(name)returns the length of the string without the null terminator (\0). C strings need this terminator to be valid, so you need to allocatestrlen(name) + 1bytes. Without the extra byte, you'll write past the allocated memory (buffer overflow) which causes undefined behavior like crashes. - Misused
strncpy:You're copying up to 50 bytes intobyteReALL, butbyteReALLonly hasstrlen(name)bytes (which is already too small). This leads to buffer overflow, corrupting memory and causing crashes. - Unhandled newline from
fgets:fgetsincludes the newline character (\n) when the user presses enter. You probably don't want that in your stored names, so we should strip it.
Corrected Code
#include <stdio.h> #include <stdlib.h> #include <string.h> void friendNamesInput(int friendNum, char **ppFriendName) { char name[50] = {0}; int i = 0; for (i = 0; i < friendNum; i++) { printf("Enter name of friend %d: ", i + 1); // Clear any leftover newline in stdin (in case previous input left it) fflush(stdin); // Read input into name buffer if (fgets(name, sizeof(name), stdin) == NULL) { // Handle input error ppFriendName[i] = NULL; continue; } // Strip the newline character if present size_t nameLen = strlen(name); if (nameLen > 0 && name[nameLen - 1] == '\n') { name[nameLen - 1] = '\0'; nameLen--; } // Allocate enough memory for the string + null terminator ppFriendName[i] = malloc(nameLen + 1); if (ppFriendName[i] == NULL) { // Handle allocation failure fprintf(stderr, "Failed to allocate memory for friend %d\n", i + 1); continue; } // Copy the string safely strcpy(ppFriendName[i], name); } } // Example usage int main() { int numFriends = 3; // First allocate an array of char pointers to hold each name char **friendNames = malloc(numFriends * sizeof(char*)); if (friendNames == NULL) { fprintf(stderr, "Failed to allocate pointer array\n"); return 1; } friendNamesInput(numFriends, friendNames); // Print the names to verify printf("\nYour friends' names:\n"); for (int i = 0; i < numFriends; i++) { if (friendNames[i] != NULL) { printf("%d: %s\n", i + 1, friendNames[i]); // Don't forget to free each name when done! free(friendNames[i]); } } // Free the pointer array itself free(friendNames); return 0; }
What Changed & Why
- Used
ppFriendName[i]to store each allocated pointer: Now each name is saved to the array passed in, so the caller can access them. - Fixed malloc size: We allocate
nameLen + 1to make space for the null terminator. - Stripped the newline: Makes the stored names clean without the extra
\n. - Added error handling: Checks for
fgetsfailure andmallocfailure to avoid crashes from unexpected issues. - Added example
mainfunction: Shows how to properly allocate the pointer array before calling the function, and how to free all memory to avoid leaks.
内容的提问来源于stack exchange,提问作者user6721998
相关产品推荐
相关产品推荐

