2013-08-18 3 views
0

Следующий код вызывает нарушение доступа на линии L2 во время выполнения, которое происходит во время второго вызова setword.Нарушение доступа, memset

Q> Где я ошибаюсь в L2, и почему нет проблем с первым memset в строке L1?

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

void setword(char ** word) 
{ 
    if (*word == NULL) 
    { 
     *word = (char *)malloc(30); 
     memset(*word, '\0', 30); //L1: OK 
    } 
    else 
    { 
     memset(*word, '\0', 30);//L2: Access violation 
    } 

    *word = "Hello"; 
    //*word shall be freed when operations are complete. 
} 
int main() 
{ 
    char * word = NULL; 

    setword(&word); //Call 1: OK 
    printf("%s\n", word); 

    setword(&word); //Call 2: NOK! 
    printf("%s\n", word); 
} 

ответ

5
*word = (char *)malloc(30); 
[...] 
*word = "Hello"; 

Второе назначение производит утечку памяти (вы потеряли указатель, возвращаемый таНос), и делает word точку потенциально только для чтения памяти - любой доступ на запись к ней приведет к непредсказуемому поведению ,

(см, например, такой вопрос: Is modification of string literals undefined behaviour according to the C89 standard? - в вашем случае, "Hello" строковый литерал Вы делаете word пункт, что при втором задании Таким образом, вы не можете изменить данные, которые word указывает на потом...)

Используйте strcpy, чтобы скопировать "hello" в динамически выделенный буфер.

+0

Я хотел бы добавить, что «Привет» является частью статических данных программы и, вероятно, действительно является доступной только для чтения памятью. OP повезло, потому что, если бы он не переписал то, что дальше ... –

+0

Спасибо большое Матем. В моем исходном коде я не приписывал что-то слово, я фактически заполнял его, используя ** word = some_char. Тем не менее, я сделал некоторую арифметику указателя с * словом, на котором я потерял исходное * слово, что привело к тому, что весь ад был потерян, как вы указали! – VivereJay

0

Вы должны знать, что после *word = "Hello" значение *word является постоянным регионом, вы можете изменить содержание этого региона.