算法与数据结构:双指针加载字符串数组的代码错误排查求助
Hey there! Let's work through the problems in your code—you've got a solid start, but there are two key issues tripping you up: the leftover newline after inputting n, and a critical memory allocation mistake that would break your array of strings.
First: The Annoying Leftover Newline
When you use scanf("%d", &n) to read the number of strings, it only reads the digits of n—the newline character you press after typing n stays in the input buffer. The first fgets call then reads this empty newline as your first "string", which is why you're seeing that blank line.
To fix this, you can add a getchar() right after scanf to consume that leftover newline:
scanf("%d", &n); getchar(); // Eat the newline left in the buffer
Alternatively, you can modify the scanf format string to ignore any whitespace (including newlines) after the number:
scanf("%d%*c", &n); // %*c reads and discards the next character (the newline)
Second: The Memory Allocation Bug
Your line A = malloc(n * sizeof(a)) is incorrect. Here's why:
Ais achar**(pointer to pointer to char), so each element ofAneeds to be achar*(pointer to a string).sizeof(a)is 50 (sinceais achar[50]), so you're allocatingn * 50bytes for pointers—but each pointer only needssizeof(char*)bytes (usually 4 or 8 bytes, depending on your system).- Worse, you're assigning every
A[i] = a—this means all elements ofApoint to the sameaarray. Every time you callfgets, you overwrite the contents ofa, so by the end of the loop, all entries inAwill be identical to the last string you input.
To fix this, you need to:
- Allocate an array of
char*pointers first. - For each string, allocate a separate block of memory (size 50, matching
a's size) and copy the input string into it.
Corrected Code
Here's the fixed version with comments explaining each change:
#include <stdio.h> #include <stdlib.h> #include <string.h> // For strcpy int main (void){ char **A, a[50]; int n, i; scanf("%d", &n); getchar(); // Fix: Consume the newline after n // Fix: Allocate array of char* pointers, not sizeof(a) A = malloc(n * sizeof(char*)); if (A == NULL) { // Always check if malloc succeeds! fprintf(stderr, "Malloc failed\n"); return 1; } for(i = 0; i < n; i++){ fgets(a, sizeof(a), stdin); // Optional: Remove the trailing newline from fgets if needed size_t len = strlen(a); if (len > 0 && a[len-1] == '\n') { a[len-1] = '\0'; } // Fix: Allocate memory for each string and copy a into it A[i] = malloc(sizeof(a)); if (A[i] == NULL) { fprintf(stderr, "Malloc failed for string %d\n", i); return 1; } strcpy(A[i], a); printf("%s\n", A[i]); } // Don't forget to free the allocated memory to avoid leaks! for(i = 0; i < n; i++){ free(A[i]); } free(A); return 0; }
Key Additional Notes
- Always check malloc returns:
malloccan fail (returnNULL) if there's not enough memory, so adding checks prevents crashes. - Free allocated memory: When you're done with the array, make sure to free each string first, then the array itself—this avoids memory leaks.
- Removing trailing newlines:
fgetsincludes the newline character in the string (if the input fits). The code above adds a check to remove it if you don't want it in your stored strings.
内容的提问来源于stack exchange,提问作者randomuser

