2009-02-10 5 views
0

Juste un simple programme pour s'habituer aux pointeurs. Le programme est censé mettre le contenu d'une partie de ma mémoire dans un tableau de caractères dans l'ordre inverse de la façon dont la mémoire est lue. C'EST À DIRE. regardant l'adresse de la mémoire descendante, et je veux le stocker dans l'ordre décroissant dans un tableau de caractères.Code C simple, avec erreur «incompatibles incompatibles dans l'affectation»

Mon compilateur ne cesse de me dire: "erreur types incompatibles dans l'affectation"

Sur la ligne avec le realloc fonction

Qu'est-ce que je fais mal? Je me semble que les deux "inverse", et le résultat de realloc devraient être des pointeurs pour le type char?

Mon 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; 
} 

Merci!

EDIT: Désolé, je mal posté ces derniers comme commentaires ci-dessous

Merci pour l'aide, le premier et le second commentaire eu! J'ai eu le #includes requis, j'ai juste oublié de les copier dans le débordement de pile. Vous aviez raison, maintenant je suis coincé sur le strlen() non-terminé. Je vais résoudre celui-là par moi-même. Merci encore!

J'ai parlé trop tôt, il compilé bien, mais il y a une erreur de logique. La boucle while s'exécutera une fois. Cependant, les boucles suivantes échouent toujours, quelle que soit la valeur initiale de i. La ligne qui provoque l'échec est la ligne qui appelle realloc

+0

Une bonne pratique pour commencer à écrire lorsque vous écrivez du code c est de lire les pages man sur les fonctions que vous appelez. Dans les systèmes * nix, vous pouvez le faire depuis la ligne de commande appelant "man functionname" ou vous pouvez taper "man functionname" dans google si vous utilisez un autre os. – CalvinR

+0

Une grande partie de s'habituer aux pointeurs, s'habitue aux avertissements du compilateur et ce qu'ils signifient! Autrement dit, nous devons aller faire toutes les erreurs habituelles. – gbarry

+0

Cela doit être l'un des morceaux de code les plus effrayants que j'ai jamais vus. –

Répondre

1

Vous ne pouvez pas réaffecter la mémoire qui n'a pas été malloced en premier lieu. Vous devez déclarer reverse comme "char *" et malloc pour commencer.

Cela vous permettra de démarrer, mais vous devriez vraiment penser à réaffecter en morceaux, plutôt que d'un octet à la fois. Oh, je n'ai pas pris la peine de corriger le fait que "reverse" n'est probablement pas terminé lorsque vous essayez le strlen - je vais laisser cela comme un exercice pour le lecteur.

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; 
} 
+0

En fait, selon la documentation sur Realloc lorsque vous lui passez un pointeur nul il va agir selon malloc et allouer la mémoire pour vous, donc il a raison à cet égard. "reverse" devrait être un char * cependant. http://linux.die.net/man/3/realloc – CalvinR

+0

Mais il ne lui passe pas une valeur nulle, il lui passe une chaîne constante. –

0

Soit:

  • Vous compilez votre code C avec un compilateur C++. C'est pourquoi il pense vous devez jeter le vide * a renvoyé par realloc à un char *. La conversion serait légal en C.

ou

  • Vous ne parvenez pas à inclure stdlib.h, de sorte que le compilateur pense realloc retours int

Modifier

A la lecture votre code à nouveau, le problème réel est que vous sont assignés à un tableau, qui n'est pas autorisé à apparaître sur le LHS d'une affectation (n'est pas un 'lvalue'). C'est bien que vous ayez accepté l'autre réponse, cependant. Il a de bons conseils.

+0

Merci pour l'aide, le premier et le deuxième commentaire l'ont obtenu! J'avais les # inclus nécessaires, j'ai juste oublié de les copier dans le débordement de la pile. Vous aviez raison, maintenant je suis bloqué sur le strlen() non-terminé. Je vais résoudre celui-là par moi-même. Merci encore! – SooDesuNe

+0

J'ai parlé trop tôt, il compilé bien, mais il y a une erreur de logique. La boucle while s'exécute une fois. Cependant, les boucles suivantes échouent toujours, quelle que soit la valeur initiale de i. La ligne qui provoque l'échec est la ligne qui appelle realloc – SooDesuNe

+0

Je suis confus par votre commentaire ".... n'est pas autorisé à apparaître sur le LHS d'une affectation (n'est pas un 'lvalue') ... "J'ai vu beaucoup d'exemples qui utilisent ce format exact. Par exemple: http://fydo.net/gamedev/dynamic-arrays. – SooDesuNe

0

Vous ne pouvez pas réaffecter de la mémoire qui n'a pas été mise en place en premier lieu.

Oui, certainement vrai, car pour réallouer, malloc doit avoir avoir des informations additionnelles sur le morceau de mémoire que vous manipuler (soit par une table de alocation bloc, ou stocké dans les 4 octets juste avant que votre pointeur). Mais vous pouvez toujours écrire:

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

Et vous n'auriez pas une erreur de compilation. Cependant, vous obtiendrez probablement une erreur de segmentation au moment de l'exécution.

Cependant, il existe une différence fondamentale dans la façon dont un compilateur C traite

char * tab = "toto"; 

et

char tab[] = "toto"; 

Dans le premier cas, onglet est un pointeur, de type char *, et est une lvalue comme n'importe quelle variable normale. Il réside probablement dans un registre la plupart du temps, ou pourrait être une adresse sur le tas. Dans le second cas, tab est un tableau, une constante, et n'est donc pas une lvalue. Il est probablement remplacé au niveau de l'assembly par une adresse qui pointe vers la section de texte de votre exécutable binaire, où résident les données de la chaîne "toto".

Questions connexes