2011-01-06 5 views
4

Nous pu initialiser un pointeur de caractère comme celui-ci en C.initialisation du pointeur doute

char *c="test";

Lorsque les points c au premier caractère (t).

Mais quand j'ai donné le code comme ci-dessous. Il donne un défaut de segmentation.

#include<stdio.h> 
#include<stdlib.h> 
main() 
{ 

    int *i=0; 
    printf("%d",*i); 
} 

Aussi quand je donne

#include<stdio.h> 
#include<stdlib.h> 
main() 
{ 
    int *i; 
    i=(int *)malloc(2); 
    *i=0; 
    printf("%d",*i); 
} 

Il a travaillé (a donné sortie 0).

Lorsque j'ai donné malloc(0), cela a fonctionné (a donné la sortie 0).

S'il vous plaît dire ce qui se passe

+0

Arrêter de couler malloc, au moins. – user562374

Répondre

5

Votre premier exemple est seg la formation de failles parce que vous essayez de de référence un pointeur NULL que vous avez créé avec la ligne:

int *i=0; 

Vous ne pouvez de - référencez un pointeur qui ne pointe à rien et attendez-vous à de bonnes choses. =)

Le deuxième segment de code fonctionne parce que vous avez réellement assigné de la mémoire à votre pointeur en utilisant malloc que vous pouvez dé-référencer. Je pense qu'il est possible pour vous d'obtenir des valeurs autres que zéro en fonction de la mémoire adjacente à l'adresse que vous avez allouée avec malloc. Je dis cela parce que typiquement un int est de 4 octets et vous avez seulement assigné 2. Lors de la référence du pointeur int, il devrait retourner la valeur comme un int basé sur les 4 octets pointés vers. Dans votre cas, les 2 premiers octets étant ce que vous avez reçu du malloc et les 2 octets adjacents étant ce qui est là ce qui pourrait être n'importe quoi et quoi que ce soit sera traité comme s'il s'agissait d'un int. Vous pourriez avoir un comportement étrange comme celui-ci et vous devriez réduire la taille de la mémoire nécessaire pour le type que vous essayez d'utiliser/pointer.
(c.-à-int *i = (int *) malloc(sizeof(int));)

Une fois que vous avez le pointage du pointeur à la mémoire qui est de la bonne taille, vous pouvez définir les valeurs en tant que telles:

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

int main (int argc, char *argv[]) 
{ 
    int *i = (int *)malloc(sizeof(int)); 
    *i = 25; 
    printf("i = %d\n",*i); 

    *i = 12; 
    printf("i = %d\n",*i); 
    return 0; 
} 

Modifier basé sur le commentaire:

Un pointeur pointe vers la mémoire et non vers des valeurs. Lors de l'initialisation char *ptr="test"; Vous n'attribuez pas la valeur de "test", vous affectez l'adresse mémoire de l'endroit où le compilateur place "test" qui est placé dans votre segment de données de processus et est en lecture seule. Si vous avez essayé de modifier la chaîne "test", vous programmez probablement seg-faute. Ce que vous devez réaliser à propos d'un caractère *, c'est qu'il pointe sur un seul caractère (c'est-à-dire le premier) de la chaîne. Lorsque vous décrierez le caractère *, vous verrez 1 caractère et un caractère seulement. C utilise des chaînes terminées nulles, et remarquez que vous ne faites pas référence à ptr lorsque vous appelez printf, vous lui passez le pointeur lui-même et cela ne pointe que sur le premier caractère. L'affichage dépend du format transmis à printf. Lorsque printf est passé au format '% c', il imprime les points ptr individuels, si vous passez le format '% p', il affiche l'adresse pointée par ptr. Pour obtenir la chaîne entière, vous transmettez '% s' comme format. Qu'est-ce que fait printf est de commencer au pointeur que vous avez passé et lire chaque octet successif jusqu'à ce qu'un null est atteint. Voici un code qui les démontre.

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

int main (int argc, char *argv[]) 
{ 
    // Initialize to data segement/read only string 
    char *ptr = "test"; 
    printf("ptr points at  = %p\n", ptr); // Prints the address ptr points to 
    printf("ptr dereferenced = %c\n", *ptr); // Prints the value at address ptr 
    printf("ptr value   = %s\n", ptr); // Prints the string of chars pointed to by ptr 

    // Uncomment this to see bad behavior! 
    // ptr[1] = 'E'; // SEG FAULT -> Attempting to modify read-only memory 

    printf("--------------------\n"); 

    // Use memory you have allocated explicitly and can modify 
    ptr = malloc(10); 
    strncpy(ptr, "foo", 10); 
    printf("ptr now points at = %p\n", ptr); // Prints the address ptr points to 
    printf("ptr dereferenced = %c\n", *ptr); // Prints the value at address ptr 
    printf("ptr value   = %s\n", ptr); // Prints the string of chars pointed to by ptr 

    ptr[1] = 'F'; // Change the second char in string to F 
    printf("ptr value (mod) = %s\n", ptr); 
    return 0; 
} 
+0

L'initialisation du pointeur de caractère est différente du pointeur entier? Puisque nous pourrions l'initialiser comme 'char * ptr =" test "' –

+0

J'ai mis à jour ma réponse par votre commentaire –

+0

Merci d'avoir élaboré. J'ai une question restante. Alors pourquoi le même concept ne fonctionne pas avec 'int * i = 12;'. Cela donne un défaut de segmentation sur les valeurs d'impression –

Questions connexes