Необъяснимое поведение в C. Нечетное против четного числа строк - PullRequest
0 голосов
/ 12 июля 2010

Так что у меня есть проблема, которую я не могу понять.Я пишу некоторый код на C. Я продолжал сталкиваться с проблемами, при которых чтение из сети казалось бы случайным образом.

Я, наконец, отследил его до количества строк в коде.Я не могу в это поверить, но я проверил это довольно подробно.

База кода довольно массивная, поэтому я не уверен в общем количестве паритетов строк.Однако я знаю, что если я добавляю нечетное число, то программа работает, и если я добавляю четное число, это не так.Я пытаюсь прочитать что-нибудь по сети, все, что я получаю, это 0.Когда он работает, я получаю правильные данные.

кто-нибудь когда-нибудь слышал что-нибудь подобное?Или есть идеи, что может быть причиной этого?Я мог видеть, что часть данных программы становилась слишком большой и начинала препятствовать пространству другого кода, но тот факт, что ее нечетная / четная вещь полностью смущает меня.

спасибо

РЕДАКТИРОВАТЬ(Добавление дополнительной информации):

Платформа представляет собой специально разработанное устройство.база кода - redboot, но она значительно изменилась для пользовательского устройства.

, например:

// Это будет работать из-за нечетного числа строк.

char* str1 = "test";
char* str2 = "test2";
char* str3 = "test3";

int i = strlen(str1) + strlen(str2) + strlen(str3);

......................................

если бы я изменил последнюю строку на

int i = strlen(str1) + str(len2);

, чтобы компилятор оптимизировал str3, тогда код больше не будет работать.Я проверял это много раз с различными длинами строк, которые приводят к одинаковому нечетному / четному поведению.(Я просто отправляюсь в журнал отладки, чтобы он не был оптимизирован. Ничего сложного с ним не сделано.)Не имеет значения, был ли он выполнен или нет, что заставляет меня поверить, что это не переполнение стека.

Ответы [ 5 ]

6 голосов
/ 12 июля 2010

Случайное время удара в темноте ...

Распространенным заблуждением при чтении из сетевых сокетов является то, что read() из 10 байтов вернет следующие 10 байтов. Не будет Он вернет до 10 байтов, и вам, возможно, потребуется несколько раз позвонить read(), чтобы получить все необходимые данные.

4 голосов
/ 12 июля 2010

Откуда вы берете утверждение, что оно имеет отношение к четности числа строк?Если я попытаюсь интерпретировать то, что вы говорите, то это говорит мне о том, что небольшие изменения в коде позволяют вызвать неожиданное поведение.Вы выделяете большие массивы или строки в стеке, а затем делаете для них read и write?В этом случае попробуйте распределить / освободить эти большие буферы динамически через malloc/free.

4 голосов
/ 12 июля 2010

Я не слышал о такой проблеме раньше.Похоже, вы очень расстроены и говорите, что ваша кодовая база довольно массивна.Если решение проблемы важно, я бы посоветовал вам попытаться воспроизвести проблему с меньшим количеством кода.Это также может помочь вам получить ответы здесь, если вы разместите некоторые примеры кода для иллюстрации вопроса.

2 голосов
/ 13 июля 2010

Вот предположение.

Предположим, что платформа 32-битная.

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

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

1 голос
/ 12 июля 2010

если у вас есть что-то вроде

char buf[10];
long var;
strcpy(buf, "ganz viel text");

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

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