Передача указателя в виде более короткого массива - PullRequest
2 голосов
/ 22 января 2020

Даст ли этот код переполнение буфера cra sh?

#include <stdio.h>

void show(char text[2]) {

  printf("%c%c\n", text[0], text[1]);

  return;
}

int main() {
  char *txt = "aabc";

  show (txt);

  return 0;
}

Я имею в виду txt имеет 4 символа (плюс '\0'), в то время как текст имеет только 2.

Ответы [ 2 ]

2 голосов
/ 22 января 2020

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

Так что в вашем случае char text[2] это не новая копия txt в основном, а скорее указатель на нее. Таким образом, вы не получите переполнение, поскольку не пытаетесь скопировать содержимое txt в char text[2], text просто указывает на него.

Например, следующий результат: 13

void test(char a[2]){
    printf("%d", strlen(a)); 
}

int main(){
    char* text = "Hello World!\n"; 
    test(text); 
}
1 голос
/ 22 января 2020

Вы ошибаетесь.

Компилятор неявно настраивает параметр, объявленный как массив, для указания на тип элемента массива.

Таким образом, это объявление

void show(char text[2]);

эквивалентно объявлению

void show(char *text );

Вы можете даже объявить функцию как

void show(char text[1000]);

В любом случае компилятор подгонит ее под объявление

void show(char *text );

. является функцией, имеющей дело с указателем на первый элемент массива, переданный функции в качестве аргумента, или со значением переданного указателя в качестве аргумента.

Таким образом, переполнение не происходит. Сам строковый литерал не перемещается из одной части памяти в другую. Это значение указателя, которое передается в функцию.

Вы несете ответственность за то, чтобы не получить доступ к переданной строке за ее пределами выделенной памяти.

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