-2

I have a pointer array named **lines, each line being 100 character long.

And have a function which adds characters to any given line and reallocates the line if it's not big enough:

void add_letter(char *line, int pos, char letter) {
    if(strlen(line) % 100 == 0){
        line = realloc(line, sizeof(char) * strlen(line) + 100);
    }
    ...

add_letter is called like this:

add_letter(lines[0], pos, ch);

line here is equal to lines[0], and in the second line, gdb returns 1 for p line == lines[0]. Here line and lines[0] are both in memory location 0x6465e0.

But after the realloc call, line becomes 0x648200, but lines[0] stays in the same and becomes an "" empty string.

What causes realloc to act like this? Because of this reason, strcat(line, newline), newline being the end result of addition doesn't work at the end of the function.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
razorx
  • 115
  • 1
  • 5
  • 1
    "What causes `realloc` to act like this?" Um... But that's exactly what `realloc` does! That's what `realloc` is for. In general case it allocates a *new* memory block at *new* memory location. How else did you expect it to behave? – AnT stands with Russia Dec 14 '16 at 20:01
  • I am using C. Not C++. – razorx Dec 14 '16 at 20:01
  • @AnT but it doesn't change lines[0] but changes line, they are the same thing. – razorx Dec 14 '16 at 20:02
  • 2
    @razorx Don't tag C++ then. – Baum mit Augen Dec 14 '16 at 20:02
  • @BaummitAugen same problem can apply to C++ as well. – razorx Dec 14 '16 at 20:03
  • 2
    @razorx: That has nothing to do with `realloc`. And no `line` and `line[0]` are not "the same thing". These are two completely unrelated, independent pointers that just happened to point to the same spot in memory. Then you decided to change one of them, while not changing the other. So, they became different. If you want to update `lines[0]` as well - it is your responsibility. – AnT stands with Russia Dec 14 '16 at 20:03
  • C11 draft standard n1570: *6.5.2.2 Function calls 4 An argument may be an expression of any complete object type. In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument. 93) A function may change the values of its parameters, but these changes cannot affect the values of the arguments.[...]* – EOF Dec 14 '16 at 20:03
  • @AnT that may be it, thanks for the answer. – razorx Dec 14 '16 at 20:07
  • @razorx: http://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value – AnT stands with Russia Dec 14 '16 at 20:12

1 Answers1

3

You are wrong here:

Here line and lines[0] are both in memory location 0x6465e0.

Both variables have value 0x6465e0, but they are in different locations. When you call realloc with line, runtime deallocates memory that line pointed to (which is 0x6465e0), allocates new memory and puts its address in line - that is 0x648200. Value of lines[0] is not influenced by this operation, but the memory where it is pointing has been freed already. Bottom line - if you reallocate you need to update all pointers that pointed to the old location with the new location

Hope this helps

Dima Ogurtsov
  • 1,487
  • 1
  • 10
  • 18