0

Pdの問題である可能性があるため、これをクロスポストしていますが、おそらく誰かがこのようなことが起こる理由を知っています.

手短に言えば、Pd (コンピューター音楽のピュアデータ) という名前のプログラムで使用している dll があります。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];

+ 1、C スタイルの文字列が持つヌル ターミネータに必要です。

その他のエラーは次のとおりです。

deletenotを使用するdelete[](new[]と組み合わせる必要がありますdelete[])。

デフォルトのコンストラクターは初期化されていnameません。

代入演算子は古い文字列を解放しないため、メモリ リークが発生します。setString同じです。

印刷しているものではpost("address: %d", name)なく、必要なアドレスを出力する場合、アドレスが指しているのではなく、オブジェクト内のアドレスです。post("address: %d", &this->name)namename

私はキャメロンに同意し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 に答える