0

我正在交叉发布这个,因为它可能是一个 Pd 问题,但也许这里有人知道为什么会发生这样的事情。

简而言之,我有一个 dll,我在名为 Pd(puredata,用于计算机音乐)的程序中使用它。我创建了一个名为 recordString 的对象,我将它与基本的 Pd API 结合使用来创建 pd 将读取的 dll。所有 Pd 需要访问的是一些简单的功能。我已经将使用 Pd API 的代码作为 recordString 的一部分。

无论如何,recordString 对象包含一个我正在使用 new 创建的 char*(我也尝试过 malloc)。当我设置 char* 的值时,它正确设置为 HELLOWORLD。我正在输出地址以确保它保持在应有的位置。

我已经确认该值是应有的,但后来当我调用一个函数来获取 char* 的值时,它以某种方式移动了 1 个字节。

有没有人听说过指针将地址更改为 1 的情况?不被告知?

无论如何,这是输出,然后是 datarecord.cpp 的代码

字符串:HELLOWORLD
长度:10
地址:32774028
地址 2:32578488

调用 postString
字符串:ELLOWORLD
长度:9
地址:32774028
地址 2:32578489

#include "m_pd.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "datarecord.h"

using namespace std;

recordString::recordString()
    :name(NULL)
{
};

recordString::recordString(const char* sourceString)
{
    this->name = new char[strlen(sourceString)+1];

    post("-------- in string constructor -----------");
    post("address: %d", &this->name);
    strcpy(this->name, sourceString );
    post("copy: %s", this->name);
};

recordString::~recordString()
{
    //delete(this->name);
    delete[] name;
    name = NULL;

    //free(this->name);
};

recordString::recordString(const recordString & rhs)
{
    post("-------- in copy constructor -----------");
    post("source: %s", rhs.name);
    post("length: %d", strlen(rhs.name));
    post("\n");

    this->name = new char[strlen(rhs.name)+1];

    strcpy(this->name, rhs.name);

    post("copy: %s", this->name);
    post("length: %d", strlen(this->name));
    post("address: %d", &name);
    post("address-2: %d", name);
    post("\n");
}

recordString & recordString::operator=(const recordString &rhs)
{
    post("-------- in operator= -----------");
    post("source: %s", rhs.name);
    post("length: %d", strlen(rhs.name));
    post("\n");

    if(name!=NULL)
    {
        delete[] name;
    }

 //this->name = (char*) malloc((strlen(rhs.name))); 
    this->name = new char[strlen(rhs.name)+1];

    strcpy(this->name, rhs.name);

    post("copy: %s", this->name);
    post("length: %d", strlen(this->name));
    post("address: %d", &name);
    post("address-2: %d", name);
    post("\n");
}

int recordString::setString(const char * sourceString)
{

    post("-------- in setString -----------");
    post("source: %s", sourceString);
    post("length: %d", strlen(sourceString));
    post("\n");

    this->name = new char[strlen(sourceString)];
    strcpy(this->name, sourceString);

    post("copy: %s", this->name);
    post("length: %d", strlen(this->name));
    post("address: %d", &name);
    post("address-2: %d", name);
    post("\n");

    return (this->name == NULL);
}


void recordString::postString()
{
    post("string: %s", this->name);
    post("length: %d", strlen(this->name));
    post("address: %d", &name);
    post("address-2: %d", name);
    post("\n");
}
4

2 回答 2

3

你的问题是你没有为你的字符串分配足够的内存

this->name = new char[strlen(sourceString) + 1];

C 样式字符串具有的+ 1nul 终止符需要 。

其他错误是:

使用deletenot delete[](new[]应该与delete[]) 配对。

您的默认构造函数name未初始化。

您的赋值运算符会泄漏内存,因为它从不释放旧字符串。setString是一样的。

当您输出您想要的地址时,您要打印的是对象内部的地址,而不是指向的post("address: %d", name)地址。post("address: %d", &this->name)namename

我必须同意 Cameron 的观点,std::string它将把你从所有这些复杂性中解救出来。

于 2013-04-06T20:57:18.720 回答
0

和几个人聊了聊,词对齐和结构填充的话题就上来了。该结构的原始代码是

typedef struct _something {
    t_object x_obj; // *this 
    recordString r;
} t_something

由于某种原因, r->name 指向的指针的值与 4 字节边界对齐。不知道为什么,但显然与结构填充有关。做了一些测试来确认这一点,它确实与 4 字节边界对齐。

我从结构中删除了 recordString r,并将其放在全局上下文中,它不再受这种对齐方式的影响。

对我来说奇怪的是,它发生在调用之间,在不同的范围内,在不同的时间,在运行时。我对编译器或打包/填充结构不太了解,但在运行时发生类似的事情似乎很危险。

无论如何,现在似乎通​​过从结构中删除对象来修复。

谢谢!我将把它打开一段时间,以防有人在运行时添加关于对齐的细节。

于 2013-04-08T23:51:29.303 回答