首页 > 解决方案 > C编程打印从函数返回的二维动态数组

问题描述

我有以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char** my_spliter(char* text){
    char* token;
    char** words;
    int c_words = 0;

    words = (char*) malloc(sizeof(char));
    token = strtok(text, ".");
    while( token != NULL ) {
        if(strlen(token)>1){
             words[c_words] = (char*) malloc(strlen(token)*sizeof(char));
             strcpy(words[c_words], token);
             c_words++;
         }
         token = strtok(NULL, ".");
    }

    for(int i=0; i<c_words; i++)
         printf("'%s' ", words[i]); //This prints the words successfully
}

void main(){
    char *my_text;
    char **list;
    
    m_text = (char*) malloc(250*sizeof(char));
    
    strcpy(my_text, ".test..tes.tested...t");
    list = my_spliter(my_text);

    printf("%s\n", list[0]); //This gives me an error
    
    size_t i;
    for (i = 0; list[i] != NULL; i++){
        printf("%s\n", list[i]); //This also gives me an error
    }
    
}

如评论中所述,我可以在 my_spliter 函数内打印列表,但我不能在它之外打印它(在 main 函数中)。

一般来说,我想知道如何打印从函数返回的二维动态数组。

标签: cdynamic-arrays

解决方案


致命错误:

  • 您必须为每个元素words分配而不是仅分配 1 个字节。
  • words[c_words] = (char*) malloc(strlen(token)*sizeof(char));不好,因为它没有为终止空字符分配空间。
  • 您必须返回数组才能main()打印数组。
  • NULL在函数中用作结束标记main(),因此my_spliter函数应该添加它。

警告:

  • 他们说您不应该将结果转换为malloc()in C
  • int main(void)您应该在托管环境中使用 standard而不是void main(),这在 C89 中是非法的,并且在 C99 或更高版本中是实现定义的,除非您有特殊原因使用非标准签名。

固定代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char** my_spliter(char* text){
    char* token;
    char** words;
    int c_words = 0;

    words = malloc(sizeof(*word)); // fix allocation size
    token = strtok(text, ".");
    while( token != NULL ) {
        if(strlen(token)>1){
             words = realloc(words, sizeof(*words) * (c_words + 2)); // 1 for current element, 1 for NULL
             words[c_words] = malloc((strlen(token)+1)*sizeof(char)); // fix allocation size
             strcpy(words[c_words], token);
             c_words++;
         }
         token = strtok(NULL, ".");
    }
    words[c_words] = NULL; // add NULL

    for(int i=0; i<c_words; i++)
         printf("'%s' ", words[i]); //This prints the words successfully

    return words; // return the array
}

int main(){ // use standard type
    char *my_text;
    char **list;
    
    m_text = (char*) malloc(250*sizeof(char));
    
    strcpy(my_text, ".test..tes.tested...t");
    list = my_spliter(my_text);

    printf("%s\n", list[0]);
    
    size_t i;
    for (i = 0; list[i] != NULL; i++){
        printf("%s\n", list[i]);
    }
    
}

分配和释放的错误检查被省略。请注意,您不需要在现代操作系统上的程序结束时释放数据,因为操作系统会释放它们。(参考:c - 当你在 malloc 之后不释放时,真的会发生什么? - 堆栈内存溢出


推荐阅读