2013-08-21 2 views
1

J'ai commencé à apprendre le C hier, donc cela peut être une question triviale, mais je ne comprends toujours pas.segfault lors de la concaténation de deux chaînes dans un petit tableau

Disons que j'ai le code suivant:

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

int main() 
{ 
    char text[8]; 
    strcpy(text, "Lorem "); 
    puts(text); 
    strcat(text, "ipsum!"); 
    puts(text); 
    return 0; 
} 

Cela se traduira par une erreur de segmentation quand (ou après) concating les cordes. Cependant, si je change la taille de text de 8 à 9, ce n'est pas le cas.

S'il vous plaît me corriger si je me trompe, mais ce que je pensais être juste: - "! Ipsum"

"Lorem" taille 6 (ou 7 avec \ 0)
- taille 6 (ou 7 avec \ 0)
"Lorem ipsum!" - taille 12 (ou 13 avec \ 0)

Alors, d'où vient le 8/9? Est-ce causé par la mise en œuvre de strcat? Ou y a-t-il quelque chose comme une longueur de tableau minimale? Ou est-ce que je fais une erreur de débutant stupide?

Merci d'avance.

+4

[comportement non défini] (http://en.wikipedia.org/wiki/Undefined_behavior) –

+0

Exécuter ce sous Valgrind (http://valgrind.org) et vous verrez qu'il ya un problème à la fois cas. – alk

+1

Et la réponse à votre question, "d'où vient le 8/9", il est tout à fait possible que votre compilateur particulier alloue de la mémoire en morceaux de 8 octets. Donc, le texte [8] attribuerait 8 octets; le texte [9] arrondirait jusqu'à 16 octets. Bien sûr, cela dépend de l'implémentation, et vous ne devriez jamais compter sur un compilateur qui le fait toujours! –

Répondre

3

C'est juste de la chance que ça ne plante pas, au moins sur Linux, je reçois *** stack smashing detected ***.

Vous essayez d'ajouter une chaîne à une autre chaîne même si le stockage de cette dernière est insuffisant. C'est un exemple de comportement indéfini (comme indiqué dans les commentaires). C est le genre de langage qui approuve toujours le programmeur avec ce qui est dans le programme et donc vous ne pouvez même pas obtenir un avertissement pour cela lors de la compilation. Assurez-vous toujours que vous avez suffisamment de mémoire dans vos tampons, il y a très peu d'équipements en C qui garantissent un comportement sûr, donc ne supposez pas des choses comme minimum array length.

+0

Eh bien, je pense que c'est quelque chose dont je devrais m'habituer, puisque j'ai seulement de l'expérience avec Java et quelques langages de script. Merci. – Griddo

+0

Oh, absolument, Java est très particulier et par exemple ne vous laissera jamais utiliser un type primitif unitalisé, alors que vous pouvez obtenir un avertissement pour cela dans 'C' si vous avez activé tous les avertissements, il vous laissera quand même courir le code supposant que vous savez ce que vous faites :) Et vous n'obtenez jamais le comportement pardonnant des langages de script qui font tellement de coulisses pour vous. C est très nu. – Nobilis

3

Lorsque vous débordez la fin d'un tableau, le comportement du programme est indéfini. Cela signifie qu'il pourrait faire ce que vous attendez de lui ou non. Il pourrait fonctionner comme si vous n'aviez pas invoqué un comportement indéfini. Il pourrait tomber en panne. Il pourrait reformater votre disque dur. Il pourrait imprimer une page vierge sur votre imprimante. Il pourrait faire toutes ces choses selon le moment où vous l'exécutez.

Vous ne pouvez pas savoir. C'est ce qu'est un "comportement indéfini". Indéfini.

Je pourrais vous donner une explication sur le comportement, mais ce serait inutile, et très spécifique au matériel et à l'implémentation.

0

Vous pouvez malloc à n'importe quelle taille que vous voulez. et même vous pouvez réallouer aussi selon l'entrée supplémentaire.

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

int main() 
{ 
    char *text; 
    text = (char *) malloc(sizeof(char) * 12); 
    memset(text, 0x0, sizeof(char) * 12); 
    sprintf(text, "%s", "Lorem "); 
    puts(text); 
    sprintf(text, "%s%s", text, "ipsum!"); 
    puts(text); 
    return 0; 
}