C 使用字符指针退出函数后出现分段错误

C 使用字符指针退出函数后出现分段错误,c,segmentation-fault,C,Segmentation Fault,我正在用C编写一个带有用户界面的代码,我在使用字符指针时遇到了一个问题。我团队的另一个人做了这样一个算法: typedef struct int index; char * buffer; //...another fields } ui_cfg; int ui_Function (ui_cfg *cfg) { char localBuffer[100]; cfg->buffer = localBuffer; printf("\n[1]cfg->

我正在用C编写一个带有用户界面的代码,我在使用字符指针时遇到了一个问题。我团队的另一个人做了这样一个算法:

typedef struct
   int index;
   char * buffer;
   //...another fields
} ui_cfg;

int ui_Function (ui_cfg *cfg)
{
   char localBuffer[100];
   cfg->buffer = localBuffer;

   printf("\n[1]cfg->buffer %p", cfg->buffer);
   printf("\n[2]localBuffer %p", localBuffer);

   Adapter(cfg->buffer);
   printf("\n[3]localBuffer %p", localBuffer);
   printf("\n[4]cfg->buffer %p", cfg->buffer);

   //...irrelevant code
}
int Adapter (char * buffer)
{
   int idx;
   idx = sprintf (buffer, "Test string");

   return idx;
}
// caller will need to free cfg->buffer when finished using
int ui_Function (ui_cfg *cfg)
{
   char* heapBuffer = malloc(100);
   cfg->buffer = localBuffer;
   // etc
}
这是一个非常非常简单的代码版本,但它有一些基本部分。在实际代码中,适配器是用第二个函数中的函数指针调用的。适配器函数执行如下操作:

typedef struct
   int index;
   char * buffer;
   //...another fields
} ui_cfg;

int ui_Function (ui_cfg *cfg)
{
   char localBuffer[100];
   cfg->buffer = localBuffer;

   printf("\n[1]cfg->buffer %p", cfg->buffer);
   printf("\n[2]localBuffer %p", localBuffer);

   Adapter(cfg->buffer);
   printf("\n[3]localBuffer %p", localBuffer);
   printf("\n[4]cfg->buffer %p", cfg->buffer);

   //...irrelevant code
}
int Adapter (char * buffer)
{
   int idx;
   idx = sprintf (buffer, "Test string");

   return idx;
}
// caller will need to free cfg->buffer when finished using
int ui_Function (ui_cfg *cfg)
{
   char* heapBuffer = malloc(100);
   cfg->buffer = localBuffer;
   // etc
}
我的问题是下一个。当我运行代码时,它在
printf(“\n[4]cfg->buffer%p”,cfg->buffer”)中抛出
分段错误
指令。但是,另一个printf工作正常,并显示相同的内存方向。我不明白为什么代码在这一点上崩溃。有什么问题吗

详细信息:
此代码在两种不同的体系结构上使用arm brcm linux gnueabi gcc和mipsel linux uclibc gcc进行编译。在ARM上,这些代码运行良好,cfg缓冲区包含“测试字符串”。在MIPSEL上,代码抛出分段错误

如下更改您的ui功能:

typedef struct
   int index;
   char * buffer;
   //...another fields
} ui_cfg;

int ui_Function (ui_cfg *cfg)
{
   char localBuffer[100];
   cfg->buffer = localBuffer;

   printf("\n[1]cfg->buffer %p", cfg->buffer);
   printf("\n[2]localBuffer %p", localBuffer);

   Adapter(cfg->buffer);
   printf("\n[3]localBuffer %p", localBuffer);
   printf("\n[4]cfg->buffer %p", cfg->buffer);

   //...irrelevant code
}
int Adapter (char * buffer)
{
   int idx;
   idx = sprintf (buffer, "Test string");

   return idx;
}
// caller will need to free cfg->buffer when finished using
int ui_Function (ui_cfg *cfg)
{
   char* heapBuffer = malloc(100);
   cfg->buffer = localBuffer;
   // etc
}
或者:

int ui_Function (ui_cfg *cfg, char* buffer)
{
  cfg->buffer = buffer;
  // etc
}
对于当前版本,localBuffer是一个堆栈变量,在函数返回时会被清除。在某些操作系统上,它可能在函数返回后仍然可以访问(可能在短时间内),但在另一些操作系统上,它将被重新用于其他用途。这就是所谓的未定义行为,是baaaad

要分配一些在函数返回时仍然存在的内存,可以从堆中分配一些内存,或者将自己的缓冲区传递给函数


完成cfg后,不要忘记释放所有使用的堆内存。

如下更改ui功能:

typedef struct
   int index;
   char * buffer;
   //...another fields
} ui_cfg;

int ui_Function (ui_cfg *cfg)
{
   char localBuffer[100];
   cfg->buffer = localBuffer;

   printf("\n[1]cfg->buffer %p", cfg->buffer);
   printf("\n[2]localBuffer %p", localBuffer);

   Adapter(cfg->buffer);
   printf("\n[3]localBuffer %p", localBuffer);
   printf("\n[4]cfg->buffer %p", cfg->buffer);

   //...irrelevant code
}
int Adapter (char * buffer)
{
   int idx;
   idx = sprintf (buffer, "Test string");

   return idx;
}
// caller will need to free cfg->buffer when finished using
int ui_Function (ui_cfg *cfg)
{
   char* heapBuffer = malloc(100);
   cfg->buffer = localBuffer;
   // etc
}
或者:

int ui_Function (ui_cfg *cfg, char* buffer)
{
  cfg->buffer = buffer;
  // etc
}
对于当前版本,localBuffer是一个堆栈变量,在函数返回时会被清除。在某些操作系统上,它可能在函数返回后仍然可以访问(可能在短时间内),但在另一些操作系统上,它将被重新用于其他用途。这就是所谓的未定义行为,是baaaad

要分配一些在函数返回时仍然存在的内存,可以从堆中分配一些内存,或者将自己的缓冲区传递给函数


完成cfg时,不要忘记释放所有使用的堆内存。

@πάνταῥεῖ 但是,在提供的代码示例中没有-没有范围外访问。我想知道,在实际代码中,您是否也在编写
idx=sprintf(buffer,“teststring”)还是字符串写得更长?@SergeyA-Well,
cfg->buffer=localBuffer
意味着可以在代码的其他部分访问
cfg->buffer
,否?@heteperfan,字符串长但小于100个字符。特别是,它有40个带NULL的圆形字符。@πάνταῥεῖ 有一个强烈的迹象表明它可能,但目前的样本并没有显示它。我倾向于认为职业训练局缺乏MCVE。@πάνταῥεῖ 但是,在提供的代码示例中没有-没有范围外访问。我想知道,在实际代码中,您是否也在编写
idx=sprintf(buffer,“teststring”)还是字符串写得更长?@SergeyA-Well,
cfg->buffer=localBuffer
意味着可以在代码的其他部分访问
cfg->buffer
,否?@heteperfan,字符串长但小于100个字符。特别是,它有40个带NULL的圆形字符。@πάνταῥεῖ 有一个强烈的迹象表明它可能,但目前的样本并没有显示它。我倾向于认为VTC缺乏MCVE。你是对的,但我在使用malloc()时也有同样的问题。我不知道原因。我使用
int适配器(char**buffer)
函数进行了测试。我实现了
适配器(&cfg->buffer)并且代码也会抛出错误。@JCMiguel那么您的适配器函数肯定正在破坏cfg结构或类似的东西。显示适配器功能。我能够解决我的问题。有一个由五个元素组成的char数组,我在其中写了一个太长的字符串,然后用
sprinf(…)
将数组的内容复制到cfg->buffer中。我认为代码抛出错误是因为退出后无法访问局部变量的内容。然而,我不理解为什么我不能用cfg->buffer访问的全部原因。我应该用完整的函数编辑我的问题吗?你是对的,但是我在使用malloc()时也有同样的问题。我不知道原因。我使用
int适配器(char**buffer)
函数进行了测试。我实现了
适配器(&cfg->buffer)并且代码也会抛出错误。@JCMiguel那么您的适配器函数肯定正在破坏cfg结构或类似的东西。显示适配器功能。我能够解决我的问题。有一个由五个元素组成的char数组,我在其中写了一个太长的字符串,然后用
sprinf(…)
将数组的内容复制到cfg->buffer中。我认为代码抛出错误是因为退出后无法访问局部变量的内容。然而,我不理解为什么我不能用cfg->buffer访问的全部原因。我应该用完整的功能编辑我的问题吗?