2014-12-07 2 views
0

Я борюсь с моими навыками программирования. Я не могу понять, что я делаю неправильно. Я просто передаю указатель от одного вызова функции к следующей функции. Я не вижу, что в этом плохого ... ??? Когда я использую Valgrind, я не могу понять, что такое ошибка.Неверное чтение размером 1

Вот дистиллированная версия моих функций.

*/ CIcp.c /* 
153int CIcp_SetUsedIOs(CIcp this, char *str, int len, dataTypes type) 
154{ 
155 ASSERT(); 
156 if(str == NULL) 
157  return 0; 
158 for(int i = 0; i < len; i++) 
159 { 
160  if(str[i] > '8' || str[i] < '0') 
161   continue; 
162  else 
163  { 
164   if((type == DI) || (type == AI)) 
165   { 
166    this->usedInputs |= (0x01 << (str[i] - '0')); 
167   } 
168   else 
169   { 
170    this->usedOutputs |= (0x01 << (str[i] - '0')); 
171   } 
172  } 
173 } 
174 log_info("ICP %d Used input [%s]", this->id, ctob(this->usedInputs)); 
175 return 0; 
176} 

char *getvalue (CParamList This, const char *name) { 
    char *result = NULL; 
    pnv currnv = This->current->nvlist; 
    while (currnv) 
    { 
     if ((strcmp(name,currnv->name)== 0)) /* 0 = match */ 
     { 
      result = currnv->value; 
      break; 
     } 
     currnv = currnv->next; 
    } 

    return result; 
} 

int LoadParams(CSdcList this) 
{ 
    pPtN tmpThread; 
    CIcp icp; 

    for(int i = 0; i < this->icp->count; i++) 
    { 
     tmpThread = findNodeByIdx(this->icp, i); 
     icp = (CIcp)tmpThread->sdc; 
     if (isname(this->cPl, tmpThread->name, this->keys.ICP_DO)) 
     { 
      char str[MAX_STR_LEN] = {0}; 
      CIcp_SetUsedIOs(icp, getvalue(this->cPl, this->keys.ICP_DO), MAX_STR_LEN, DO); 
     } 
    } 
} 

Valgrind дает мне этот выход. Когда я читаю документ, он говорит: «Это происходит, когда ваша программа читает или записывает память в месте, которое, по мнению Memcheck, не должно». Но я не вижу, что я делаю это ... !!

==5695== Invalid read of size 1 
    ==5695== at 0x406ABF: CIcp_SetUsedIOs (CIcp.c:160) 
    ==5695== by 0x40A9E2: LoadParams (CSdcList.c:1163) 
    ==5695== by 0x407B84: getCSdcList (CSdcList.c:396) 
    ==5695== by 0x40DC5F: main (main.c:48) 
    ==5695== Address 0x5b86e0c is 0 bytes after a block of size 12 alloc'd 
    ==5695== at 0x4C2AB80: malloc (vg_replace_malloc.c:292) 
    ==5695== by 0x40D47F: newnvpair (config.c:164) 
    ==5695== by 0x40D7A9: process (config.c:244) 
    ==5695== by 0x40D90B: readParamFile (config.c:276) 
    ==5695== by 0x407973: getCSdcList (CSdcList.c:351) 
    ==5695== by 0x40DC5F: main (main.c:48) 
    ==5695== 
    ==5695== Invalid read of size 1 
    ==5695== at 0x406AD3: CIcp_SetUsedIOs (CIcp.c:160) 
    ==5695== by 0x40A9E2: LoadParams (CSdcList.c:1163) 
    ==5695== by 0x407B84: getCSdcList (CSdcList.c:396) 
    ==5695== by 0x40DC5F: main (main.c:48) 
    ==5695== Address 0x5b86e0c is 0 bytes after a block of size 12 alloc'd 
    ==5695== at 0x4C2AB80: malloc (vg_replace_malloc.c:292) 
    ==5695== by 0x40D47F: newnvpair (config.c:164) 
    ==5695== by 0x40D7A9: process (config.c:244) 
    ==5695== by 0x40D90B: readParamFile (config.c:276) 
    ==5695== by 0x407973: getCSdcList (CSdcList.c:351) 
    ==5695== by 0x40DC5F: main (main.c:48) 
    ==5695== 

Я потянув меня слышащий в отчаянии ... Спасибо заранее.

+1

Какая строка функции 'CIcp_SetUsedIOs '- это номер строки 160? Вы вызываете функцию с правильными аргументами (помните, что индексы основаны на нуле, т. Е. От нуля до размера минус один)? Если 'len' ошибочно, вы можете индексировать за пределами' str'. В вашем случае выделение памяти (для 'str' предположительно) равно' 12', поэтому 'len' должно быть не более 12 (хотя это должно включать пробел для завершающего символа' '\ 0''). –

+1

Я не вижу смысла использовать 'str' в настройке' CIcp_SetusedIOs', поэтому что-то говорит мне, что строка, полученная вами от 'getvalue()', не так долго, как вы подозреваете. если это завершенная строка, вы должны использовать терминатор в качестве точки остановки; не предполагая 'MAX_STR_LEN'. – WhozCraig

ответ

-2
'this' is a reserved word (in C++) so best to not use it. 

what is a 'pnv'? Is it some kind of struct. 
Perhaps you could include the struct definition 

what is ASSERT();? I know of an assert(something is true); 

what is a Cicp? 

perhaps the code should initialize usedInputs and usedOutputs to zero 
before setting bits 

hopefully, usedInputs and usedOutputs are larger than a single char 
(though the call to function ctob() may mean char to binary? 
because a single char only has 8 bits. and the offsets allowed are 
0 ... 8 I.E. a 9 bit range. 

this code snippet: (0x01 << (str[i] - '0')); 
since the shift value (str[i] - '0') can be 8, and the working size of the shifted value 
is only 0x01 (a single byte), some the shifts can result in a bit of a problem. 

the function loadparams() will not cleanly compile 
because the function indicates a return value of type int, 
but no such return statement is in the function 

There is plenty of other problems with the code, but the valgrind message 
is probably about ...inputs |= and ...outputs |= statements 
1

Я сомневаюсь, что все ваши «имя» строк точно размера MAX_STR_LEN. Но если вы посмотрите на свою петлю в CIcp_SetUsedIOs, вы всегда будете зацикливаться на MAX_STR_LEN элементов. Вероятно, вы должны проверить на '\0' и вырваться из цикла. Либо это, либо передать правильную длину строки в функцию.

+0

Вы совершенно правы! За последние три месяца я занимался кодированием этого проекта, чтобы сделать это. Теперь я начинаю ослепнуть по своему собственному коду. Мне определенно нужно немного поспать ... И большое вам спасибо за то, что вы не торопитесь! Это означает для меня мир. –

Смежные вопросы