无论malloc大小,strcpy工作?

Dav*_*rný 2 c string malloc pointers

我目前正在学习C编程,因为我是一个python程序员,我不完全确定C的内部工作原理.我只是偶然发现了一个非常奇怪的事情.

void test_realloc(){
  // So this is the original place allocated for my string
  char * curr_token = malloc(2*sizeof(char));

  // This is really weird because I only allocated 2x char size in bytes 
  strcpy(curr_token, "Davi");
  curr_token[4] = 'd';
  // I guess is somehow overwrote data outside the allocated memory?
  // I was hoping this would result in an exception ( I guess not? )      

  printf("Current token > %s\n", curr_token);

  // Looks like it's still printable, wtf???
  char *new_token = realloc(curr_token, 6);
  curr_token = new_token;
  printf("Current token > %s\n", curr_token);
}


int main(){
  test_realloc();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

所以问题是:为什么我能够将更多的字符写入字符串而不是分配的大小?我知道我应该自己处理mallocated内存,但这是否意味着当我在指定内存外写字时没有迹象表明出现了问题?

我想要完成的事情

  1. 分配一个4 char(+ null char)字符串,我会在其中写出4个字符
  2. 重新分配内存以表示我姓名的最后一个字符

dav*_*mac 7

知道我应该自己处理mallocated内存,但这是否意味着当我在指定内存外写字时没有任何迹象表明存在问题?

欢迎来到C编程:).一般来说,这是正确的:你可以做错事,并且不会立即收到反馈.实际上,在某些情况下,您可以做错事,并且永远不会在运行时看到问题.但是,在其他情况下,您会看到崩溃或其他对您没有意义的行为.

关键术语是未定义的行为.这是一个你应该熟悉的概念,如果你继续用C编程.它就像听起来一样:如果你的程序违反了某些规则,行为是未定义的 - 它可能会做你想要的,它可能会崩溃,它可能会做有些不同.更糟糕的是,它可能会在大多数情况下做你想做的事情,但偶尔会做一些不同的事情.

正是这种机制允许C程序快速运行 - 因为它们不会在运行时执行很多可能用于Python的检查 - 但它也使C变得危险.编写错误的代码并且不知道它很容易; 然后在其他地方进行细微的更改,或使用不同的编译器或操作系统,代码将不再按您的意愿运行.在某些情况下,这可能会导致安全漏洞,因为不受欢迎的行为可能会被利用.

  • @DavidČerný使用_sanitizers_或工具.Gcc和Clang编译器具有清理程序选项,可以在运行时捕获您的错误(尽管它们无法捕获所有错误).像_valgrind_这样的工具可以做同样的事情._static分析_工具(例如来自Clang的_scan-build_)可以检查您的代码并发现一些错误. (4认同)