【问题标题】:Segmentation fault on using std::string inside a dynamically allocated struct [duplicate]在动态分配的结构中使用 std::string 时出现分段错误 [重复]
【发布时间】:2014-09-07 17:57:40
【问题描述】:

我正在尝试一个简单的程序来了解如何使用指向结构指针数组的指针。

我写了这个小程序:

#include <stdio.h>
#include <stdlib.h>

struct A
{
   char* a1;
};

void fn1(A **d, int n)
{
    printf("5 \n");
    for(int i=0;i<n;i++)
    {
        printf("val: %s \n",d[i]->a1);
    }
    printf("6 \n");
}
int main(int argc, char **argv) {
    printf("0 \n");
    A *a,*b,*c;
    printf("1 \n");
    a = (A*)malloc(sizeof (A));
    b = (A*)malloc(sizeof (A));
    c = (A*)malloc(sizeof (A));
    printf("2 \n");
    a->a1 = "hi";
    b->a1 = "bye";
    c->a1 = "see you";
    printf("3 \n");
    A *d[] = {a,b,c};
    printf("4 \n");
    fn1(d,3);
    printf("7 \n");
    printf("Program successfully completed \n");
}

程序正确编译和执行,我得到了这个输出:

0 
1 
2 
3 
4 
5 
val: hi 
val: bye 
val: see you 
6 
7 
Program successfully completed 

但是在编译时,我在deprecated conversion from string to char* 上收到了这些警告,因此我决定将结构中的char* 更改为std::string。我把程序改成:

#include <stdio.h>
#include <string>
#include <stdlib.h>

struct A
{
   std::string a1;
};

void fn1(A **d, int n)
{
    printf("5 \n");
    for(int i=0;i<n;i++)
    {
        printf("val: %s \n",d[i]->a1.c_str());
    }
    printf("6 \n");
}
int main(int argc, char **argv) {
    printf("0 \n");
    A *a,*b,*c;
    printf("1 \n");
    a = (A*)malloc(sizeof (A));
    b = (A*)malloc(sizeof (A));
    c = (A*)malloc(sizeof (A));
    printf("2 \n");
    a->a1 = "hi";
    b->a1 = "bye";
    c->a1 = "see you";
    printf("3 \n");
    A *d[] = {a,b,c};
    printf("4 \n");
    fn1(d,3);
    printf("7 \n");
    printf("Program successfully completed \n");
}

现在程序编译正确,但运行时我得到了segmentation fault(core dumped)。甚至第一个 printf("0"); 都没有显示出来。谁能解释一下我在这里犯了什么错误?

【问题讨论】:

  • malloc 和需要构造的对象相处得不是很好。使用new
  • @RetiredNinja 如果是这样,为什么没有打印第一个 printf ?在执行 malloc 行之前,代码执行应该是正常的吧?
  • 修复第一个程序中的警告:在struct A的定义中,更改为char const *a1;
  • @MattMcNabb 是的,我可以做到,但我只是说我尝试了什么以及我是如何遇到这个错误的
  • 关于出现的 printf 行:输出在 C++ 中缓冲,因此您的程序可能会在缓冲的行进入屏幕之前崩溃。在每个printf 之后添加fflush(stdout);

标签: c++ c string pointers struct


【解决方案1】:

malloc 不适合创建非 POD 对象。它分配内存但不调用任何构造函数。所以你的a-&gt;a1 行访问了一个尚未构造的字符串,导致未定义的行为。

要正确分配和构造对象,请使用:

a = new A;

在任何 C++ 程序中使用 malloc 是不好的风格(充其量)

【讨论】:

  • 如果 mallocing 是问题,为什么不打印第一个 printf?
  • 输出在 C++ 中缓冲,因此您的程序可能会在缓冲的行进入屏幕之前崩溃。在每个 printf 之后添加fflush(stdout);
猜你喜欢
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多