繁体   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