简体   繁体   中英

C Programming Print 2d dynamic Array Returned from function

I have the code below:

#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
    }
    
}

I can print the list inside the my_spliter function as mentioned in the comment, but I can't print it outside of it (in main function).

Generally, I want to know how to print 2D dynamic array returned from a function.

Fatal errors:

  • You have to allocate for each elements of words instead of allocating only 1 byte.
  • words[c_words] = (char*) malloc(strlen(token)*sizeof(char)); is bad because it don't allocate space for terminating null-characters.
  • You have to return the array to let main() print the array.
  • You are using NULL as end mark in the main() function, so the my_spliter function should add that.

Warnings:

  • They say you shouldn't cast the result of malloc() in C .
  • You should use standard int main(void) in hosted environment instead of void main() , which is illegal in C89 and implementation-defined in C99 or later, unless you have some special reason to use non-standard signature.

Fixed code:

#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]);
    }
    
}

Error checking of allocations and freeing are omitted. Note that you won't need to free data at the end of program on modern OS because the OS will free them. (reference: c - What REALLY happens when you don't free after malloc? - Stack Overflow )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM