【问题标题】:The char* member of a struct gets overwritten by strcmp?结构的 char* 成员被 strcmp 覆盖?
【发布时间】:2013-07-17 15:38:43
【问题描述】:

我有一个自己实现的列表:

struct NodeComposition {
    Int32 index;
    Int8 address;
    char* label;
    NodeComposition* next;
};

我正在使用以下方法创建新结构,而根元素的标签使用 NULL 初始化,稍后会更改。

NodeComposition ListManager::getNewNode(char* label, Int8 address)
{
    NodeComposition* newNode = new NodeComposition;
    newNode->address = address;
    newNode->label = label;
    newNode->next = 0;
    newNode->index = -1;
    return *newNode;
}

为了检查是否存在特定的“标签”,我实现了以下方法:

NodeComposition* ListManager::labelExists(char* label)
{
UInt32 i = 0;
NodeComposition* conductor = &rootNode;

// Traverse through list
while(i < elements)
{
    // Label has been found

    if (strcmp(conductor->label, label) == 0)
    {
        return conductor;
    }

    /* Advancing in list */
    else
    {
        if(conductor->next != 0)
        {
            conductor = conductor->next;
        }

        else
        {
            /* Error: Null reference found in conductor->next */
            return NULL;
            //return Errors::NULL_REFERENCE;
        }
    }

    i++;
}
/* label not found */
return NULL;
}

我的问题来了:

  • 我调用了labelExists(char* label)方法(带有两个元素的链表)
  • 比较两个字符串后,它会更改第一次迭代中第二个元素的成员label的值

这些数据是我主内存中的一些随机垃圾,我不知道它为什么会这样。此外,该代码恰好在一小时前工作。至少我认为它确实如此,因为我不记得更改任何代码。

有人有想法吗?

谢谢!

编辑: 这是一些额外的代码

NodeComposition newNode = getNewNode(label, address);
ListManager::addNode(newNode);


Int32 ListManager::addNode(NodeComposition node)
{
node.index = elements;
lastNode->next = &node;
lastNode = &node;
elements++;
return lastNode->index;
 }

【问题讨论】:

  • 如果您使用 C++ 工作,那么强烈喜欢 std::string 而不是所有这些原始的 char *strcmp 东西。
  • 我在 C++ 中工作,但我不允许使用 std::string :(
  • 我想看看调用getNewNode的函数。
  • 由于strcmp 不是“写入”的函数,显然不是“strcmp”导致问题(除非实现严重错误)。实际存储label的代码是什么?
  • 您的代码存在内存泄漏:您正在使用指针和operator new 创建结构的本地实例(为什么?为什么不使用局部变量?),而您是按值返回指针的解引用值,所以原始数据泄露。避免在 C++ 中使用指针!!!并且不要做真正可怕的事情,例如取消引用指针并按值返回结果!

标签: c++ list pointers struct char


【解决方案1】:

肯定不是strmcp,所以我们不要关注那个。您应该先清理此代码。存在内存泄漏和损坏。

开始:

NodeComposition ListManager::getNewNode(char* label, Int8 address)
{
    NodeComposition* newNode = new NodeComposition; // $#!^!memory allocated
    newNode->address = address;
    newNode->label = label;  // $#!^! is label allocated on stack or heap? possible leak & corruption
    newNode->next = 0;
    newNode->index = -1;
    return *newNode; // $#!^!return by value. newNode is now lost! memory leak
}

然后在您的附加代码中:

NodeComposition newNode = getNewNode(label, address); // $#!^! getting a copy of the "newNode" only. This copy is allocated in stack.   
ListManager::addNode(newNode); //$#!^! adding a stack object onto linked list


Int32 ListManager::addNode(NodeComposition node)
{
    node.index = elements;
    lastNode->next = &node;
    lastNode = &node;  //node is actually allocated from stack, not heap! likely memory corruption here!
    elements++;
    return lastNode->index;
 }

【讨论】:

  • 其实这不是我尝试实现 getNewNode 方法的唯一方法。最初,我在堆栈上创建了一个 newNode,例如 NodeComposition newNode; newNode-&gt;address ...。但我认为我遇到了一些缓冲区溢出问题。但是,调试器在strcmp 之前显示正确的值。但我想你是对的 - 它必须是内存泄漏。我明天再试一次。谢谢
【解决方案2】:

我得到了答案.. 我修改了我的代码如下:

Int32 ListManager::addNode(NodeComposition* node)
{
node->index = ++elements;
lastNode->next = node;
lastNode = node;
return lastNode->index;
}

NodeComposition* ListManager::getNewNode(char* label, Int8 address)
{
NodeComposition* newNode = new NodeComposition;
newNode->address = address;
newNode->label = label;
newNode->next = 0;
newNode->index = -1;
return newNode;
}

NodeComposition* ListManager::labelExists(char* label)

指针的使用帮助了我 - 谢谢你们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-24
    • 2020-03-11
    • 1970-01-01
    • 2012-12-30
    • 2011-02-05
    • 2021-12-09
    • 2018-10-19
    • 1970-01-01
    相关资源
    最近更新 更多