#Pointer loses value when return.

26 messages · Page 1 of 1 (latest)

vernal widget
#

I'm making a trim function, i'm doing the trimLeft first, but i'm when i change the value, in the function i can print after the strcpy, but after the return, when i check the value i just get random ram values.

void trim(char *s) {
    size_t original_len = strlen(s);
    if (original_len == 0)
        return;

    if (s[0] == ' ') {
        int count = 0;
        for (int i = 0; i < original_len; i++) {
            if (s[i] != ' ')
                break;
            count += 1;
        }

        char *trimLeft = newStr(original_len - count + 1);
        for (int i = count; i < original_len; i++)
            trimLeft[i - count] = s[i];
        trimLeft[original_len - count] = '\0';
        
        free(s);
        s = (char *)malloc(sizeof(char) * strlen(trimLeft) + 1);
        strcpy(s, trimLeft);
    }
}

The full code: https://github.com/MarceloLuisDantas/Tager-Assembler

To test run cmake --build . && ./Tager Test\ Files/test1.txt

GitHub

Contribute to MarceloLuisDantas/Tager-Assembler development by creating an account on GitHub.

reef zodiacBOT
#

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 use !howto ask.

light vine
#

Yeah, you realloc the pointer in that function.
And I fear that the calling function quite possibly uses the old pointer upon returning, which will cause a crash.
If you want to do this, then you should pass a double pointer to the function.

vernal widget
#

a pointer to a pointer?

#

I don't understand why this, could you pls give me a example?

molten delta
# vernal widget I don't understand why this, could you pls give me a example?

This sequence:

free(s);
s = (char *)malloc(sizeof(char) * strlen(trimLeft) + 1);

Destroys the value you were passed in s. When this function was called you were given a local copy of s which the free(s) call destroys. You then replace the local copy of that address with a newly malloc'd buffer. However, the caller still has the original value for s which is now pointing somewhere in the free heap. If you want to create a new buffer that the caller will be able to use, you have to pass a pointer to his pointer so that you can modify it in this function.

vernal widget
#

ok ok, i'll try this

molten delta
#

Just a thought to consider... Trimming leading and trailing spaces can only make the string smaller. Perhaps consider finding the start and end of the remaining string, moving the '\0' to the new end and then moving the shortened string up to the start of the buffer. You then eliminate any memory allocation. Be careful about constant strings however. Also, be careful about overlapping memory movement. (memmove vs. memcpy)

vernal widget
#

https://onlinegdb.com/NTWA3TnOK i make a simpler version of the problem, and here works, even if i free and realloc the value

molten delta
#

If you say so...

vernal widget
molten delta
#

define "wasting"

vernal widget
vernal widget
molten delta
#

define "works". Things can appear to work that are built on undefined behaviour but are nevertheless broken. freeing and mallocing a passed string and expecting the caller to have the new string is undefined behaviour.

#

if you wish to resize the memory block, by all means do so. just implement it correctly using defined behaviour. Pass a pointer to the pointer so you can resize it for the caller.

#

Compile and run your simpler version with gcc -g -fsanitize=address and run it. You will see a heap use after free error.

vernal widget
#

do you mean this?

molten delta
#

This is what I get when I run your code compiled this way (gcc -g -fsanitize=address test.c) in the debugger.

vernal widget
#

I'm trying with pointer to pointer, but i cant get the values by index to copy, i get a segfault trying to

for (int i = 1; i < len; i++) {
    copy[i - 1] = *s[i];
}

i can print the *s, get the len, everthing, but when i try to get the values by index crash

#

and when i look up for i just found about list of strings

molten delta
#

s[i] binds tighter than the dereference. try (*s)[i]

#

you want to index the address pointed to by s, not s itself

vernal widget
#

thanks for the help

#

!solved