You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 are char* 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 using char* tab_address which is a single string pointer. You need a pointer to an array of char* 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 a char* (pointer), not a single char. You need sizeof(char*) * (j + 1) (the +1 is for the NULL terminator required by your problem statement).
  • Wrong return value & memory leak: You return ptr (a random char variable) instead of your allocated array, and the free(tab_address) line comes after return—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 const string (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 of char* pointers). This array is allocated on the heap using malloc, 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 a char* (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 +1 is to make space for the string's null terminator ('\0'), which is required for C strings to be valid.
  • Error handling: If any malloc fails, 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* str pointer—use a temporary pointer (temp) to traverse the string instead.
  • Always track whether you're inside a word (in_word flag) to handle consecutive separators correctly.
  • Make sure every string you allocate has a null terminator added, otherwise functions like printf will read past the end of the memory and cause undefined behavior.

内容的提问来源于stack exchange,提问作者Christopher Bolard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 23:03:13