Home > Software design >  Unexpected problem with Bidimensional char VLA pointer
Unexpected problem with Bidimensional char VLA pointer

Time:12-09

I did a simple program that splits a string in substrings, using the whitespace as a split reference. The program was working as expected, so I've decided to put this code inside a function that is called "substring_whitespace".This function return a size_t value which is the number of substring's. The function arguments are char* buffer[] and char* string. Both are pointers, the first will store the substring's, and the second is the string that'll be splited.

Here is the code:

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

size_t substring_whitespace(char* buffer[],char* string) {
    size_t initial_string_size = strlen(string)   1;
    char actual_string[initial_string_size];
    char strings[initial_string_size][initial_string_size];
    strcpy(actual_string,string);
    size_t c = 0;
    for(; c<initial_string_size; c  ) {
        size_t first_whitespace_index = strcspn(actual_string," ");
        char substring[first_whitespace_index];

        for(size_t d = 0; d<=first_whitespace_index; d  ) {
            if(d == first_whitespace_index)
                substring[first_whitespace_index] = 0;
            else
                substring[d] = actual_string[d];
        }
        size_t actual_string_length = strlen(actual_string);
        size_t new_actual_string_length = (actual_string_length - first_whitespace_index)   1;
        char new_actual_string[new_actual_string_length];
        for(size_t d = 0,i = first_whitespace_index   1; i<=actual_string_length   1; i  ,d  ) {
            if(i == actual_string_length)
                new_actual_string[d] = 0;
            else
                new_actual_string[d] = actual_string[i];
        }
        strcpy(actual_string,new_actual_string);
        strcpy(strings[c],substring);
        buffer[c] = strings[c];
        if(new_actual_string_length == 1)
            break;
    }
    return   c;\
}

int main() {
    char string[1000];

    fgets(string,sizeof(string)/sizeof(string[0]),stdin);
    string[strcspn(string,"\n")] = 0;

    char* buffer[strlen(string)   1];
    size_t buffer_length = substring_whitespace(buffer,string);

    for(int d = 0; d<buffer_length; d  ) {
        printf("\n%s",buffer[d]);
    }

}

After I test, the results were not as expected, so during my debug I detect that the char were being changed after get off the function by pointer. This behavior is only detectable if I try to print the buffer strings in the main.

CodePudding user response:

strings is a local variable whose lifetime ends when the function returns. The easiest fix is to copy the string when assigning a value buffer[c]:

        buffer[c] = strdup(strings[c]);

Another option is to change the design and return an array of ranges relative to your input string. For example struct range { char *s; size_t len; };, and if string is "hello world" the function could return [{string, 5}, {string 6, 5}].

  • Related