丢失字符串数据c ++

时间:2012-02-08 20:59:40

标签: c++ arrays string

我正在尝试基于此messageStruct构建一个messageQueue

struct MessageStruct{
    public: std::string msg;     // what is the msg
    public: int prior;           // how important is this msg
};

这就是一个MessageQueue,它需要像vector / priorityQueue(自制版本正常工作)一样,但我把一堆东西放在上面,就像这样。

int size = 20;
// constructor takes number of entries to start with
MessageQueue * queue = new MessageQueue(size);
// used as a transport mechanism
MessageStruct * msg = new MessageStruct();
msg->prior = 0;
msg->msg = "queue exists";
queue->getMsg(msg);
// increasing size does not cause memory issue,
//  use for example of dynamic size.
... other stuff is happening
size *= 2;
for (int ii = 0; ii < size; ii++){
    msg->prior = 0;
    msg->msg = "creating thing " + ii;
    // puts this message in the queue,
    //  and increases queue size if needed
    queue->getMsg(msg);
}
... // other stuff is happening
msg->prior = 10;
msg->msg = "program terminated correctly";
queue->queueDump();
delete msg;
msg = 0;
delete queue;
queue = 0;

这段代码没有错误,并且所有内存都没有问题地发布,虽然它的输出看起来像这样(我在xml中生成输出以获得完整性):

<message> 
    <index>0</index>
    <msg>program terminated correctly</msg>
    <priority>10</priority>
</message>
<message> 
    <index>1</index>
    <msg>init(). queue exists</msg>
    <priority>0</priority>
</message>
<message> 
    <index>2</index>
    <msg>reating thing </msg>
    <priority>0</priority>
</message>
<message> 
    <index>3</index>
    <msg>eating thing </msg>
    <priority>0</priority>
</message>
<message> 
    <index>4</index>
    <msg>ating thing </msg>
    <priority>0</priority>
</message>
<message> 
    <index>5</index>
    <msg>ting thing </msg>
    <priority>0</priority>
</message>
<message> 
    <index>6</index>
    <msg>ing thing </msg>
    <priority>0</priority>
</message>
<message> 
    <index>7</index>
    <msg>ng thing </msg>
    <priority>0</priority>
</message>
<message> 
    <index>8</index>
    <msg>g thing </msg>
    <priority>0</priority>
</message>
<message> 
    <index>9</index>
    <msg> thing </msg>
    <priority>0</priority>
</message>
<message> 
    <index>10</index>
    <msg>thing </msg>
    <priority>0</priority>
</message>
<message> 
    <index>11</index>
    <msg>hing </msg>
    <priority>0</priority>
</message>
<message> 
    <index>12</index>
    <msg>ing </msg>
    <priority>0</priority>
</message>
<message> 
    <index>13</index>
    <msg>ng </msg>
    <priority>0</priority>
</message>
<message> 
    <index>14</index>
    <msg>g </msg>
    <priority>0</priority>
</message>
<message> 
    <index>15</index>
    <msg> </msg>
    <priority>0</priority>
</message>

看起来字符串正在生成和放置,但为什么要删除前导字符?

3 个答案:

答案 0 :(得分:3)

这里有很多错误。

MessageStruct * msg = new MessageStruct();
msg->prior = 0;
msg->msg = "queue exists";
queue->getMsg(msg);

size *= 2;
for (int ii = 0; ii < size; ii++){
    msg->prior = 0;
    msg->msg = "creating thing " + ii;
   queue->getMsg(msg);
}

首先,一个样式错误。 “获取”是一个动词,通常用来表示“我希望对象给我一些东西”。你的方法“getMsg()”实际上意味着“我给对象一些东西”,这会让看到你代码的人感到困惑。您应该将其重命名为“pushMsg()”,“addMsg()”或类似的东西。为了完全准确,您不应使用缩写。 “pushMessage()”可能是这里最好的名字。

接下来,您正在针对指针做出基本错误。您分配一个MessageStruct,然后不断更改其数据。您需要为插入队列的每个数据片段创建一个新结构,如下所示:

MessageStruct * msg = new MessageStruct();
msg->prior = 0;
msg->msg = "queue exists";
queue->getMsg(msg);

size *= 2;
for (int ii = 0; ii < size; ii++){
    MessageStruct * anotherMsg = new MessageStruct();
    anotherMsg->prior = 0;
    anotherMsg->msg = "creating thing " + ii;
    queue->getMsg(anotherMsg);
}

(如果你的MessageQueue实现创建了你通过指针传递的结构的完整副本,你可以忽略这个错误,但我认真考虑修改该设计以更密切地遵循std :: vector的行为。)

最后,您不能使用“mystring + mynumber”将数字附加到C ++中的字符串。在您的代码中,这是一个标准的C字符串:

"creating thing"

C-string是一个表示ASCII码的数字数组。考虑C如何处理数组的简单方法只是想象它们是指向顺序内存块的指针。如果我向指针添加一个整数,我得到的是该指针的内存地址加上我的整数。所以,在这种情况下,你要获得的字符串是:

"creating thing" + 0 = "creating thing"
"creating thing" + 1 = "reading thing" // Pointer + 1 gives a string starting at "r"
"creating thing" + 2 = "eading thing" // Pointer + 2 gives a string starting at "e"
Etc.

这是字符串和数组在C:

中的工作方式
string + integer == string[integer]

我猜你是从C#或JavaScript背景来的。 C和C ++并没有那么有用。

答案 1 :(得分:2)

你认为工作正常的一切都很可能会增加问题。在您显示的代码中,您修改了相同的消息对象,好吧,这不是问题,但如果您的队列实现没有正确添加每条消息,则会出现问题。我会从那里开始。

答案 2 :(得分:1)

需要为将int转换为字符串的代码引入方法

//----------
// attempts to convert a int to a string
//----------
string toString(int value) {   // may need to specify std::
    string result = "";
    bool negative = false;
    if ( value < 0 ) {
        negative = true;
        value *= (-1);
    }
    do {
        string tmpstr = "0";
        tmpstr[0] += value%10;
        result = tmpstr + result;
        value /= 10;
    } while ( value != 0);
    if ( negative ) {
        result = "-" + result;
    }
    return result;
}

然后修改

msg->msg = "creating thing " + ii;

msg->msg = "creating thing " + toString(ii);

这在重复中可能成本很高,但唯一的另一个选择可能是调用一个不能真正保存任何内容的字符串构建器