怪异:指针地址不会改变,但内容关闭1

时间:2013-04-06 20:48:23

标签: c++ char shared-memory memory-address

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

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

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

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

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

无论如何,这是输出,接下来是datarecord.cpp的代码

string: HELLOWORLD
length: 10
address: 32774028
address-2: 32578488

calling postString
string: ELLOWORLD
length: 9
address: 32774028
address-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");
}

2 个答案:

答案 0 :(得分:3)

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

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

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

其他错误包括:

使用delete而非delete[]new[]应与delete[]配对)。

您的默认构造函数将name取消初始化。

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

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

我必须同意Cameron,std::string将使您免于所有这些复杂性。

答案 1 :(得分:0)

与几个人交谈,出现了词对齐和结构填充的主题。最初的结构代码是

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

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

我从struct中删除了recordString r,并将其放在全局上下文中,它不再受此对齐的影响。

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

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

谢谢!如果有人在运行期间有关于对齐的具体细节,我会暂时保持这种状态。