Потеря строковых данных c ++ - PullRequest
0 голосов
/ 09 февраля 2012

Я пытаюсь построить messageQueue на основе этого messageStruct

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 ]

3 голосов
/ 09 февраля 2012

У вас есть несколько ошибок здесь.

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.)

Наконец, вы не можете добавлять числа к строкам в C ++, используя «mystring + mynumber». В вашем коде это стандартная C-строка:

"creating thing"

C-строка - это массив чисел, которые представляют коды ASCII. Упрощенный способ думать о том, как С работает с массивами, - просто представить, что они являются указателями на последовательный блок памяти. Если я добавлю целое число к указателю, то получу адрес памяти этого указателя плюс мое целое число. Итак, в этом случае строки, которые вы получаете:

"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 ++ не очень полезны.

2 голосов
/ 09 февраля 2012

Все, что вы уволили с работы, скорее всего, усугубляет проблему.В коде, который вы показали, вы изменяете тот же объект сообщения, хорошо, не проблема, но это проблема, если ваша реализация очереди не добавляет каждое сообщение правильно.Я бы начал там.

1 голос
/ 09 февраля 2012

необходимо ввести метод в коде, который преобразовал 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);

это может быть дорогостоящим в повторении, но единственная другая опция, вероятно, вызывает конструктор строк, который ничего не сохраняет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...