[英]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)
原始代碼有幾處錯誤:
它實際上從未初始化任何存儲(主要問題)
它被硬編碼為“ 2個元素”
“ fun()”或多或少無關緊要
如果您具有“分配”功能,則可能還需要相應的“免費”
建議更改:
#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.