#No idea what is happening

29 messages · Page 1 of 1 (latest)

slate heron
#
void parse_line(const char *line, char **fields) {
    int index = 0;   
    char *line_copy, *save;
    char *token = NULL;

    line_copy = save = strdup(line);
    assert(line_copy != NULL);

    while((token = strsep(&line_copy, ";")) != NULL)
        fields[index++] = token;
        
    free(save);
}

Hey guys!
After freeing save the first 2 fields are just gone the others are fine (they are 7 btw). Can someone just elucidate my mind on what is happening?

devout sequoiaBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.

slate heron
#

The gdb print is after free(save), before that everything is fine

olive elbow
#

!man strsep

devout sequoiaBOT
#

strsep - extract token from string

Synopsis
#include <string.h>

char *strsep(char **restrict stringp, const char *restrict delim);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

strsep():
    Since glibc 2.19:
        _DEFAULT_SOURCE
    Glibc 2.19 and earlier:
        _BSD_SOURCE

olive elbow
#

strsep does not allocate new memory, and instead just overwrite the seperator with the null terminator then give you a pointer to the same memory

#

For memory issues, try using address sanitizer. It will complain when you do something wrong

devout sequoiaBOT
#
How To Use Sanitizers

Sanitizers are tools which generate additional code in your program that can catch many common programming mistakes,
such as:

General Advice

Not all sanitizers can be combined, but when they can, use e.g.:
-fsanitize=address,undefined to combine them.
Always compile with debug info to get line numbers, variable names, etc.

MSVC 19.27+ and VS 2019 16.9+
Sample Program
int main(void) {
    int x;
    return x;
}
`-fsanitize=memory -g` Output

SUMMARY: MemorySanitizer: use-of-uninitialized-value /tmp/test.cpp:3:5 in main
Exiting
(3:5 is line and column of return)

slate heron
olive elbow
#

try not freeing save, as that would cause fields to point to freed memory

#

I think

slate heron
#

Yeah that will work but I won't be able to free the strdup and I'm parsing files with GB, so the leaks are significative

olive elbow
#

you can free(fields[0])

#

;compile

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

void parse_line(const char *line, char **fields) {
    int index = 0;   
    char *line_copy, *save;
    char *token = NULL;

    line_copy = save = strdup(line);

    while((token = strsep(&line_copy, ";")) != NULL)
        fields[index++] = token;
        
    printf("save:      %p\n", save);
    printf("fields[0]: %p\n", fields[0]);
}

int main() {
  char* fields[3];
  parse_line("hello;world;bye", fields);
  free(fields[0]);
}
tender skiffBOT
#
Program Output
save:      0x6d8eb0
fields[0]: 0x6d8eb0
slate heron
#

Oh

#

Then I don't need save variable

olive elbow
#

looks like it

slate heron
#

I created save because line_copy has memory allocated by strdup that I can't free because of strsep modifications on the pointer

#
while((nread = getline(&line, &len, fptr)) != -1) {
        char **fields = malloc(sizeof(char*) * n_fields);
        parse_line(line, fields);
        (*function_ptr)(fields, catalog);
        free(fields);
}
#

this should do it then

olive elbow
#

free fields[0] before freeing fields

#

other than that, it should work

slate heron
#

Thanks

olive elbow
#

remember it is a pointer to a pointer, so each levels needs to be freed

devout sequoiaBOT
#

@slate heron Has your question been resolved? If so, run !solved :)

slate heron
#

!solved