views:

2300

answers:

3

Just a simple program to get used to pointers. The program is supposed to put the contents of a portion of my memory into a character array in reverse order of how the memory is read. I.E. looking at descending memory address, and I want to store it in descending order in a character array.

My compiler keeps telling me: "error incompatible types in assignment"

On the line with the realloc function

What am I doing wrong? I seems to me that both "reverse", and the result of realloc should be pointers to type char?

My code:

int main(){
char  first[]="hello mark", strng='h', reverse[]="";
char* ptr=&first[10];
int i=0;
    while(ptr > (&strng-0xf4240)){
      printf("%c", *ptr--);
      reverse = realloc(reverse, (i++ * sizeof(char)));
      reverse[strlen(reverse)-i] = *ptr;
    }
printf("%s", reverse);
return 0;
}

Thank you!

EDIT: Sorry I mis-posted these as comments below

Thanks for the help, the first and second comment got it! I did have the required #includes, I just forgot to copy them into stack overflow. You were right, now I'm stuck on the non-null terminated strlen(). I'll solve that one on my own. Thanks again!

I spoke too soon, it compiled alright, but there is a logic error. The while loop will execute one time. However, subsequent loops still fail, regardless of the initial value of i. The line that causes the failure is the the line that calls realloc

+1  A: 

You can't realloc memory that wasn't malloced in the first place. You should declare reverse as "char *" and malloc it to start with.

This will get you going, but you really should think about reallocing in chunks, rather than one byte at a time. Oh, I didn't bother to fix the fact that "reverse" is probably not null terminated when you try the strlen - I'll leave that as an exercise for the reader.

int main(){
char  first[]="hello mark", strng='h';
char* reverse;
char* ptr=&first[10];
reverse = (char*)malloc(1);
reverse[0] = '\0';
int i=0;
    while(ptr > (&strng-0xf4240)){
        printf("%c", *ptr--);
        reverse = (char*)realloc(reverse, (i++ * sizeof(char)));
        reverse[strlen(reverse)-i] = *ptr;
    }
printf("%s", reverse);
return 0;
}
Paul Tomblin
Actually according to the documentation on Realloc when you pass it a null pointer it will act as per malloc and allocate the memory for you, so he is right in that regard. "reverse" should be a char * however. http://linux.die.net/man/3/realloc
CalvinR
But he doesn't pass it a null, he passes it a constant string.
Paul Tomblin
A: 

Either:

  • You are compiling your C code with a C++ compiler. That's why it thinks you need to cast the void* returned by realloc to a char*. The conversion would be legal in C.

or

  • You failed to include stdlib.h, so the compiler thinks realloc returns int

Edit

On reading your code again, the actual problem is that you are assigning to an array, which isn't allowed to appear on the LHS of an assignment (isn't an 'lvalue'). It's good that you accepted the other answer, though. It has some good advice.

fizzer
Thanks for the help, the first and second comment got it!I did have the required #includes, I just forgot to copy them into stack overflow.You were right, now I'm stuck on the non-null terminated strlen(). I'll solve that one on my own.Thanks again!
SooDesuNe
I spoke too soon, it compiled alright, but there is a logic error.The while loop will execute one time. However, subsequent loops still fail, regardless of the initial value of i. The line that causes the failure is the the line that calls realloc
SooDesuNe
I'm confused by your comment "....Isn't allowed to appear on the LHS of an assignment (isn't an 'lvalue')..." I've seen lots of examples that use this exact format. For example: http://fydo.net/gamedev/dynamic-arrays.
SooDesuNe
You can't do 'char reverse[]="";' followed by 'reverse = something;' Your link assigns to an element of an array, not the whole array.
fizzer
A: 

You can't realloc memory that wasn't malloced in the first place.

Yes, definitely true, since in order to reallocate, malloc has to have have some additionnal information on the chunk of memory you manipulate (either through a block alocation table, or stored in the 4 bytes just before your pointer). But you could still write:

char * ptr1 = malloc(16);
char * ptr2 = ptr1 + 8;
ptr2 = realloc(ptr2,32);

And you would not have a compiler error. You would still probably get a segfault at run time, though.

However, there is a fundamental difference in the way a C compiler treats

char * tab = "toto";

and

char tab[] = "toto";

In the first case, tab is a pointer, of type char *, and is a lvalue like any normal variable. It probably resides in a register most of the time, or could be an address on the heap. In the second case, tab is an array, a constant, and is thus not an lvalue. It is probably replaced at assembly level by an address that points to the text section of your binary executable, where the data for the string "toto" resides.

Varkhan