Pointeur sur une variable locale en dehors du champ de sa déclaration

Disons que j’ai une structure représentant un document PDF pdf et une structure représentant l’une de ses pages pdf_page :

 typedef struct pdf_page { int page_no; pdf_page *next_page; char *content; } pdf_page; typedef struct { pdf_page *first_page, *last_page; } pdf; 

De mon main() , j’appelle create_pdf_file(pdf *doc) :

 void main() { pdf doc; create_pdf_file(&doc); // reading the linked list of pages here } 

Supposons que create_pdf_file ceci:

 void create_pdf_file(pdf *doc) { for (int i = 0; i last_page->next_page = p; } } 

(Il s’agit simplement d’un exemple de code source. Aucun traitement de liste n’est donc affiché. De toute évidence, les membres de first_page et de dernière page du last_page pdf doivent être définis en premier.)

Ma question: si doc->first_page – ainsi qu’aux autres pages de la liste liée – après l’appel de create_pdf_file() dans ma main() , est-il possible que des erreurs de segmentation surviennent du fait que hors de son contexte “?

(Je ne suis pas sûr d’avoir garanti que l’emplacement de mémoire correspondant ne sera pas utilisé pour autre chose.)

Si oui, comment puis-je éviter cela?

Merci.

oui, p est une variable locale stockée dans la stack. À la fin de la durée de vie (à chaque itération de la boucle), tout pointeur sur celle-ci devient invalide. vous devez allouer chaque page avec malloc () et la libérer () une fois que vous avez terminé. cela ressemblerait à:

 for (int i = 0; i < 10; i++) { pdf_page* p = malloc(sizeof(pdf_page)); p->page_no = i; p->contents = "Hello, World!"; doc->last_page->next_page = p; } 

et lorsque vous appelez votre fonction, vous devez passer un pointeur sur doc:

 create_pdf_file(&doc); 

est-il possible que j’obtienne des erreurs de segmentation en raison de la “sortie de la variable locale p de son contexte”?

Une fois que le bloc dans lequel p est déclaré terminé, tout pointeur sur p est invalide (un “pointeur suspendu”) et toute tentative de déréférencement d’un tel pointeur correspond au comportement non défini. En d’autres termes, ne le faites pas: vous pourriez avoir des erreurs de segmentation ou tout autre comportement (y compris la corruption de mémoire aléatoire ou l’utilisation de mauvaises données sans condition d’erreur).

(Je ne suis pas sûr d’avoir garanti que l’emplacement de mémoire correspondant ne sera pas utilisé pour autre chose.)

Vous avez garanti que la durée de vie de p est plus courte qu’un pointeur sur p .

Si oui, comment puis-je éviter cela?

Utilisez malloc pour allouer de manière dynamic une région mémoire de la taille correcte pour contenir le datum. N’oubliez pas de free la mémoire lorsque vous n’en avez plus besoin.