Home > Enterprise >  Passing back C struct with a char pointer array included fails
Passing back C struct with a char pointer array included fails

Time:10-28

I'm struggling with this split function based on C. After returning the struct by reference from the strSplit() function the token handle seems wrong. The variable sd->tokens is the right address, but I cannot get the tokens. But they are correct because inside the function I can get it. How can I resolve this and what is the reason for this behavior. All remaining variables in the struct are ok.

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

struct splitResult {
    char *source;
    long lSource;
    int  result;
    char **tokens;
};

typedef struct splitResult splitResultStruct;

splitResultStruct * strSplit(char *source, char *delimiter);

int main(int argc, const char * argv[]) {

    char *source = "part1.part2.part3";
    splitResultStruct *sd;
    
    sd = strSplit(source, ".");
    
    printf("%d tokens found\n", sd->result);
    
    for(int i=0; i<sd->result; i  ) {
        printf("%s\n", sd->tokens[i]);
    }

    return 0;
}


splitResultStruct * strSplit(char *source, char *delimiter) {
    
    // Defines the result struct
    splitResultStruct sData, *sDataPtr;
    
    sDataPtr = &sData;
    
    sData.source = source;
    // Gets the length of source string
    sData.lSource = strlen(source);
    // Don't split if empty string is given
    if(sData.lSource == 0) {
        sData.result = -1;
        return sDataPtr;
    }
    // Allocate memory according teh size of source string
    char data[sData.lSource];
    // Copy the source into the allocated memory
    strcpy(data,source);
    // Just count the tokens
    char *token = strtok(data, delimiter);
    int tc = 0;
    while (token != NULL)
    {
        token = strtok(NULL, delimiter);
        tc  ;
    }
    if(tc == 0) {
        sData.result = -1;
        return sDataPtr;
    }
    // Defines an array of char pointer with the dimension of the number of tokens
    sData.result = tc;
    char *tokens[tc];
    // Resets the token engine
    strcpy(data,source);
    // Strip out the first token found
    token = strtok(data, delimiter);
    tokens[0] = token;
    tc = 0;
    while (token != NULL)
    {
        // Strip out one token and store them into the token array
        token = strtok(NULL, delimiter);
        tc  ;
        tokens[tc] = token;
    }
      
    sData.tokens = tokens;

    for(int i=0; i<sData.result; i  ) {
        printf("%s\n", sData.tokens[i]);
    }

    return sDataPtr;
}

CodePudding user response:

Remember, never return a pointer to local variable. Local variables are destoryed when the function returns.

Try:

sDataPtr = malloc(sizeof(splitResultStruct));

Or:

static splitResultStruct sData;
splitResultStruct* sDataPtr;

CodePudding user response:

Ok, guys, got it regarding the struct memory. Changed the code to this version, so the struct will be declared in main and a pointer is passed. The functions returns nothing but changes the struct itself. But the tokens remains empty. Not a clue...

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

struct splitResult {
    char *source;
    long lSource;
    int  result;
    long tSize;
    char **tokens;
};

typedef struct splitResult splitResultStruct;

void strSplit(splitResultStruct *, char *source, char *delimiter);

int main(int argc, const char * argv[]) {

    char *source = "part1.part2.part3";
    splitResultStruct sd;
    
    strSplit(&sd, source, ".");
    
    printf("%d tokens found\n", sd.result);
    
    for(int i=0; i<sd.result; i  ) {
        printf("%s\n", sd.tokens[i]);
    }

    return 0;
}


void strSplit(splitResultStruct *sData, char *source, char *delimiter) {
    
    sData->source = source;
    // Gets the length of source string
    sData->lSource = strlen(source);
    // Don't split if empty string is given
    if(sData->lSource == 0) {
        sData->result = -1;
    }
    // Allocate memory according teh size of source string
    char data[sData->lSource];
    // Copy the source into the allocated memory
    strcpy(data,source);
    // Just count the tokens
    char *token = strtok(data, delimiter);
    int tc = 0;
    while (token != NULL)
    {
        token = strtok(NULL, delimiter);
        tc  ;
    }
    if(tc == 0) {
        sData->result = -1;
    }
    // Defines an array of char pointer with the dimension of the number of tokens
    sData->result = tc;
    char *tokens[tc];
    // Resets the token engine
    strcpy(data,source);
    // Strip out the first token found
    token = strtok(data, delimiter);
    tokens[0] = token;
    tc = 0;
    while (token != NULL)
    {
        // Strip out one token and store them into the token array
        token = strtok(NULL, delimiter);
        tc  ;
        tokens[tc] = token;
    }
    
    sData->tokens = tokens;
    
    for(int i=0; i<sData->result; i  ) {
        printf("%s\n", sData->tokens[i]);
    }
}

Result:

Part1
Part2
Part3
3 tokens found
(null)
(null)
(null)
Program ended with exit code: 0
  •  Tags:  
  • c
  • Related