C语言字符串分割函数实现求助:数组返回与malloc使用问题
Fixing Your String-to-Word-Array Function
Hey there! Let's break down the issues in your code, walk through a corrected implementation, and clear up your confusion about returning arrays and proper malloc usage.
Key Issues in Your Current Code
Let's start with the obvious bugs that are causing compile errors and logic failures:
- Mixing characters and string constants: You're using
" "and"\0"(which arechar*string literals) when you should use single quotes for individual characters:' 'and'\0'. Worse, you're using assignment (=) instead of comparison (==) in your conditionals—this completely breaks your logic and will cause unexpected behavior. - Wrong pointer type: Your function is declared to return
char**(an array of string pointers), but you're usingchar* tab_addresswhich is a single string pointer. You need a pointer to an array ofchar*values. - Broken word counting: Your counting loop stops at the first space, and doesn't handle leading/trailing separators or multiple consecutive separators. It also doesn't iterate through the entire input string.
- Incorrect malloc size: You're allocating
sizeof(char) * j—but each element in your array is achar*(pointer), not a single char. You needsizeof(char*) * (j + 1)(the+1is for the NULL terminator required by your problem statement). - Wrong return value & memory leak: You return
ptr(a randomcharvariable) instead of your allocated array, and thefree(tab_address)line comes afterreturn—so it never runs, leading to memory leaks. - No word copying: Your code doesn't actually copy the words from the input string into new memory. You need to allocate space for each word and copy its content, since you can't just store pointers to parts of the original
conststring (well, you could, but the problem likely expects separate allocated strings, and modifying the original isn't allowed anyway).
Corrected Implementation
Here's a working version that addresses all these issues, follows your problem requirements, and handles edge cases like multiple separators and trailing words:
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> // For isalnum() to check alphanumeric chars char **my_str_to_word_array(const char *str) { // Step 1: Count the number of words in the input string int word_count = 0; const char *temp = str; int in_word = 0; // Flag to track if we're inside a word while (*temp != '\0') { if (isalnum((unsigned char)*temp)) { if (!in_word) { word_count++; in_word = 1; } } else { in_word = 0; } temp++; } // Allocate array to hold word pointers (+1 for NULL terminator) char **word_array = malloc(sizeof(char*) * (word_count + 1)); if (word_array == NULL) { perror("Failed to allocate word array"); return NULL; } // Step 2: Extract each word and store it in the array temp = str; int array_index = 0; in_word = 0; const char *word_start = NULL; while (*temp != '\0') { if (isalnum((unsigned char)*temp)) { if (!in_word) { word_start = temp; in_word = 1; } } else { if (in_word) { // Calculate word length and allocate memory for it int word_length = temp - word_start; word_array[array_index] = malloc(sizeof(char) * (word_length + 1)); if (word_array[array_index] == NULL) { // Clean up already allocated memory if malloc fails for (int i = 0; i < array_index; i++) { free(word_array[i]); } free(word_array); perror("Failed to allocate memory for word"); return NULL; } // Copy the word and add null terminator strncpy(word_array[array_index], word_start, word_length); word_array[array_index][word_length] = '\0'; array_index++; in_word = 0; } } temp++; } // Handle the last word if the string ends with a word if (in_word) { int word_length = temp - word_start; word_array[array_index] = malloc(sizeof(char) * (word_length + 1)); if (word_array[array_index] == NULL) { for (int i = 0; i < array_index; i++) { free(word_array[i]); } free(word_array); perror("Failed to allocate memory for final word"); return NULL; } strncpy(word_array[array_index], word_start, word_length); word_array[array_index][word_length] = '\0'; array_index++; } // Add NULL terminator to the array as required word_array[array_index] = NULL; return word_array; } int main(void) { char str[50] = "Hello world! This is a test-string."; char **words = my_str_to_word_array(str); if (words == NULL) { return 1; } // Test print the words for (int i = 0; words[i] != NULL; i++) { printf("Word %d: %s\n", i + 1, words[i]); free(words[i]); // Free each individual word's memory first } free(words); // Then free the array of pointers return 0; }
Answers to Your Specific Questions
1. How to correctly return the array to main?
- The function returns a
char**(a pointer to an array ofchar*pointers). This array is allocated on the heap usingmalloc, so it persists after the function finishes (unlike stack-allocated arrays which are destroyed when the function exits). - In
main, you receive this pointer, use it, and then must free it properly: first free each individual word (since each word is also heap-allocated), then free the array of pointers itself. Skipping this causes memory leaks.
2. Is malloc being used correctly?
- Pointer array allocation: We use
malloc(sizeof(char*) * (word_count + 1))because each element in the array is achar*(pointer size varies by system, usually 4 or 8 bytes), and we need an extra slot for the NULL terminator. - Word allocation: For each word, we allocate
sizeof(char) * (word_length + 1)—the+1is to make space for the string's null terminator ('\0'), which is required for C strings to be valid. - Error handling: If any
mallocfails, we clean up all previously allocated memory before returning NULL. This prevents memory leaks from partial allocations.
3. Pointer mistakes to avoid
- Don't modify the original
const char* strpointer—use a temporary pointer (temp) to traverse the string instead. - Always track whether you're inside a word (
in_wordflag) to handle consecutive separators correctly. - Make sure every string you allocate has a null terminator added, otherwise functions like
printfwill read past the end of the memory and cause undefined behavior.
内容的提问来源于stack exchange,提问作者Christopher Bolard
相关产品推荐
相关产品推荐

