读取 malloc()ed 对象中的字符串错误字符时出错。为啥? [复制]

Posted

技术标签:

【中文标题】读取 malloc()ed 对象中的字符串错误字符时出错。为啥? [复制]【英文标题】:Error reading characters of string error in malloc()ed object. Why? [duplicate]读取 malloc()ed 对象中的字符串错误字符时出错。为什么? [复制] 【发布时间】:2021-04-13 00:52:53 【问题描述】:

我正在 Visual Studio 中使用 C++。 我在使用这个结构时遇到了问题:

struct TreeNode

    string info;
    TreeNode* left, * right;
;
typedef struct TreeNode* ExpTree;

喜欢这个函数:

ExpTree createNode(string info)

    TreeNode* temp;
    temp = (TreeNode*)malloc(sizeof(TreeNode));
    if (temp == NULL)
    
        cout << "Out of space!\n";
        return (temp);
    
    temp->left = NULL;
    temp->right = NULL;
    temp->info = info;
    return temp;
;

当我尝试在主函数中运行它时:

ExpTree tree = NULL;
tree = createNode(expresie);
cout << tree->info;

它不打印任何内容并使用以下代码退出:-1073741819

调试后我看到程序停在这一行:temp-&gt;info = info;,说&lt;Error reading characters of string&gt;

我对此进行了一些研究,发现这更多地与糟糕的代码设计有关,而不是与单一解决方案的某个问题有关。

那么我在这里做错了什么?

【问题讨论】:

你为什么在这里使用mallocmalloc 只会分配内存,不会初始化任何类。使用 new 代替,甚至更好的是标准容器和智能指针。 嗨@churill,这似乎足以做出回答,不是吗? @Yunnosch 可能,但同时我也经常看到这个错误。我相信它可能有一个很好的副本。 这能回答你的问题吗? What is the difference between "new" and "malloc" and "calloc" in C++? 和 this 也是相关的。 我认为它可以回答。但我怀疑任何首先使用malloc() 的人可能会问“如果这有区别,那我为什么需要在我的代码中使用它?”。 【参考方案1】:

我认为建议的副本在技术上确实回答了这个问题。 但这里有一些关于如何解释这里问题的细节。

C“字符串”实际上并不存在,只是包含char的内存,通常以'\0'结尾。对它们所做的一切都是由那些只期望内存中的 chars 的函数完成的。

C++ std::strings 不同,它们是对象,带有方法、重载运算符等。 正如您所观察到的,它们确实需要初始化,否则在几乎所有用例中都会失败。

初始化是用new()而不是malloc()完成的。 这就是为什么您应该使用new() 以及为什么(正如您现在已经确认的那样)它可以解决您的问题。

【讨论】:

好点,是的,这比复制更进一步:)【参考方案2】:

这里是解决方案。使用以下代码:

TreeNode* temp = new TreeNode();
//temp = (TreeNode*)malloc(sizeof(TreeNode));

现在解释一下。 malloc 只分配指定大小的内存。它不会初始化它。在您的情况下,当您在结构中使用 string 时,它是一个需要初始化的类,如果没有适当的初始化,则赋值行为是未定义的。

重新建议使用 new,因为它确保不仅结构而且包括 string info; 在内的所有组件都被正确初始化。

【讨论】:

以上是关于读取 malloc()ed 对象中的字符串错误字符时出错。为啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

我试图通过espeak传递一些字符串,它读取它们但我得到“分段错误”

使用 FS 读取字符串返回此错误:位置 0 处 JSON 中的意外标记 r

分段错误 - C 编程

Malloc 结构中的字符串

语法错误第 0 行,第 84 列:错误:预期的字符串结尾,得到 'f9f03b9a61c46db91ed492c862a3083'

文件中的错误字符