簡體   English   中英

從struct **初始化struct-segfault

[英]Initializing struct from struct** - segfault

我正在嘗試初始化一個結構,從一個指針到一個指針。 我正在使用init函數。 但是,這會造成段錯誤。 我試圖從中初始化的指針是在數組中定義的。 當數組的大小設置為1時,不會發生段錯誤。

typedef struct{
  int a;
}myStruct;

void init_struct(myStruct** s){
  (*s)->a=10;
}

void fun(myStruct** sp){
  init_struct(sp);
}

int main(){
  myStruct* s[2];
  fun(&s[0]);
}

我知道這是因為我不應該訪問內存,但是為什么在這種情況下我不允許訪問? 當數組的大小為1時為什么可以? (我假設行為不確定)

這是學校作業的簡化部分,因此不允許我更改“主要”的內容。

使用myStruct* s[2] ,您可以為兩個指向myStruct指針保留內存,但是不初始化這些指針是為了使它們指向有效的myStruct對象。 然后,取消引用此類(未初始化的)指針會產生未定義的行為(很有可能發生段錯誤)。

像這樣的命令

s[0] = malloc(sizeof(myStruct));

應該至少針對第一個指針解決此問題。

如果您不能更改“ main”的內容。 你可以試試

void init_struct(myStruct** s) {
    (*s) = malloc(sizeof(myStruct));
    (*s)->a=10
}

發布的代碼無法實際為實際的struct實例分配任何內存。

因此,嘗試編寫指針指向的位置正在寫入應用程序不擁有的內存

請注意, myStruct * s[2]只是聲明了一個由2個單位初始化的指針組成的數組(指向myStruct類型的結構)。

指針很可能指向無效的內存,您可以通過以下表達式在init_struct進行訪問: (*s)->a (如果您還不知道,它等效於s[0]-> ) 。

您可以通過分配適合該結構的內存來修復無效的內存訪問:

s[0] = malloc(sizeof s[0]);

您還應該檢查malloc成功分配了內存:

if (s[0] == NULL) {
    return; // error
}

然后,您可以自由地寫入剛分配的myStruct的未初始化成員:

s[0]->a = 10;

請注意,除非您還釋放分配的內存,否則應用程序將發生內存泄漏:

free(s[0]);

此外,您可以使用非常有用的工具valgrind檢查錯誤,該工具應該為您提供以下輸出:

$ valgrind ./a.out
==12820== Memcheck, a memory error detector
==12820== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12820== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==12820== Command: ./a.out
==12820== 
==12820== 
==12820== HEAP SUMMARY:
==12820==     in use at exit: 0 bytes in 0 blocks
==12820==   total heap usage: 1 allocs, 1 frees, 8 bytes allocated
==12820== 
==12820== All heap blocks were freed -- no leaks are possible
==12820== 
==12820== For counts of detected and suppressed errors, rerun with: -v
==12820== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

原始代碼有幾處錯誤:

  1. 它實際上從未初始化任何存儲(主要問題)

  2. 它被硬編碼為“ 2個元素”

  3. “ fun()”或多或少無關緊要

  4. 如果您具有“分配”功能,則可能還需要相應的“免費”

建議更改:

#include <stdio.h>
#include <malloc.h>

typedef struct myStruct {
  int a;
} myStruct_t;

myStruct_t** init_struct_array(int nelms){
  int i;
  myStruct_t **sArray = malloc(sizeof (myStruct_t*)*nelms);
  for (i=0; i < nelms; i++) {
    sArray[i] = malloc(sizeof (myStruct_t));
    sArray[i]->a = i;
    /* Any other initialization you might want goes here... */
  }
  return sArray;
}

void free_struct_array(myStruct_t **sArray, int nelms){
  int i;
  for (i=0; i < nelms; i++) {
    free(sArray[i]);
  }
  free(sArray);
}

int main(){
  int i, n = 2;
  myStruct_t** s = init_struct_array(n);
  /* Use your array here... */
  for (i=0; i < n; i++) 
    printf ("s[%d]->a=%d...\n", i, s[i]->a);
  free_struct_array(s, n);
}

您可能還希望將“ typedef”以及“ init_struct_array()”,“ free_struct_array”以及所有其他相關“操作”的原型放到自己的.h頭文件中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM