2017-02-22 20 views
2

Я написал этот кодПочему этот код не меняет строку и вызывает переполнение буфера?

#include <stdio.h> 

int main() 
{ 
    char String[] = "Hello the world!"; 
    char *pointer = String; 
    int i; 

    printf(" %s\n", pointer); 

    pointer = "Helllooooo the worlldddddd"; 
    printf("Hello %s\n", pointer); 
    printf("Hello %s\n", String); 

    return 0; 
} 

, но я не могу понять, как эта линия работает нормально.

pointer = "Helllooooo the worlldddddd"; 

, но я получил этот выход

Hello the world! 
Hello Helllooooo the worlldddddd 
Hello Hello the world! 

Как вы видите, это не может изменить String значение, но он показывает больше, чем исходное число символов. Разве это не должно привести к переполнению буфера? Разве это не уничтожит другие переменные?

+1

«Привет, мир!» И «Helllooooo the worlldddddd» - это две разные строки, расположенные в двух разных частях памяти. С помощью 'pointer = ...' вы устанавливаете 'pointer' как адрес любой из этих строк (т. Е. Устанавливаете его для указания на эту строку). –

ответ

6

Когда вы пишете строку

pointer="Helllooooo the worlldddddd"; 

Вы не говорите «взять массив, на который указывает pointer и переписать его содержимое строки "Helllooooo the worlldddddd",» а «изменить , какая строкаpointer точки на так что теперь он указывает на строку ""Helllooooo the worlldddddd". " Это объясняет, почему вы печатаете оригинальную строку, когда вы напрямую печатаете String - вы никогда ее не модифицировали. В результате вам не нужно беспокоиться о переполнении массива здесь, поскольку вы на самом деле ничего не пишете.

С другой стороны, если бы вы написали

strcpy(pointer, "Helllooooo the worlldddddd"); 

, который на самом деле делает копию содержимое новой строки в буфер, на который указывает pointer, то вы бы есть переполнение буфера, который будет проблемой. Но обратите внимание, что это совсем другая операция, которая явно говорит «скопируйте содержимое этой строки в это место», а не «измените, где этот указатель указывает».

+1

@JohnH - Я не верю, что 'String' считается' const', неявным или иным образом, поэтому, хотя больше места нельзя добавить в 'String', например, с' realloc (...) ', его можно изменить. Если бы это было неявное 'const', я бы подумал, что это приведет к ошибке времени компиляции, а не к ошибке во время выполнения. Существует ли конкретная среда, в которой вы наблюдали иначе? – ryyker

+1

@JohnH, no 'String' должен быть изменчивым. Он не указывает на строковый литерал, но полностью отдельный массив 'char', который не является' const' квалифицированным. Таким образом, нет никакой проблемы с его модификацией. (Очевидно, есть проблема с размером.) –

1

вы инициализировали указатель, который указывает на строку «Привет мир» char *pointer=String; пока все хорошо.
first printf printf(" %s\n",pointer);, вы напечатали указатель, указывающий на «Привет, мир».
Затем вы устанавливаете указатель на новую строку «Hellloooooo the worlldddd» pointer="Helllooooo the worlldddddd";.
, тогда вы напечатали указатель, который указывает в этом случае на «Hellloooooo the worlldddd» printf("Hello %s\n",pointer);.
last printf вы напечатали строку «Привет мир» printf("Hello %s\n",String);.
Примечание :. ((Takecare, что вы напечатали во второй printf("Hello %s\n",String); и третьей PRINTF printf("Hello %s\n",String); строки привет, которая будет печататься до значения указателя или строки))

1

еще один быстрый вариант для вас, чтобы рассмотреть при обработке строк:
Строковая функция strdup(...); позволяет копировать существующую строку во вновь созданную строку за один простой шаг.(или, по меньшей мере, один, в котором вся сложность была отведенной в сторону):

char *pointer = strdup("Helllooooo the worlldddddd"); 

Новая строка pointer теперь может быть использован, чтобы содержать любую строку до len длинной, где len определяется как:

int len = strlen(pointer);//len is 26 after using strdup(...); above 

Так, например, потому что ваш пример строка короче len:

char String[]="Hello the world!";//length is 16 

вы можете скопировать его в pointer без переполнения буфера:

strcpy(pointer, String); 

Строки, созданные с помощью strdup(...): необходимо free'd, чтобы избежать утечек памяти. Вызов следующее, когда вы закончите с помощью pointer:

free(pointer); 
1
#include <stdio.h> 

int main() 
{ 
char String[]="Hello the world"; // the string 
char *pointer=String;    // pointer to string 
char i;       //counter 

printf(" %s\n",pointer);   // print current value of pointer 

pointer="number of char";   // new value to replace the string 
for (i=0;i<14;i++)    // you cannot change the content of array without using loop 
{ 
String[i] = pointer[i];   // char i in string = ti char i in pointer 
} 
printf("Hello %s\n",pointer); // print value of pointer 
printf("Hello %s\n",String); // print value of string 

return 0; 
} 

я думаю, что вы пытаетесь сделать.

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