malloc…意外行为c编程 #包括 #包括 #包括 无效foo(字符**ptr) { *ptr=malloc(0);//分配一些内存** strcpy(*ptr,“你好世界”); } int main() { char*ptr=0; //使用指向指针的指针调用函数 foo&ptr; printf(“%s\n”,ptr); //释放内存 免费(ptr); 返回0; }

malloc…意外行为c编程 #包括 #包括 #包括 无效foo(字符**ptr) { *ptr=malloc(0);//分配一些内存** strcpy(*ptr,“你好世界”); } int main() { char*ptr=0; //使用指向指针的指针调用函数 foo&ptr; printf(“%s\n”,ptr); //释放内存 免费(ptr); 返回0; },c,malloc,C,Malloc,它也在运行 #include<stdio.h> #include<malloc.h> #include<string.h> void foo( char ** ptr) { *ptr = malloc(0); // allocate some memory** strcpy( *ptr, "Hello World"); } int main() { char *ptr = 0; // call function with a poi

它也在运行

#include<stdio.h>
#include<malloc.h>
#include<string.h>

void foo( char ** ptr)
{
   *ptr = malloc(0); // allocate some memory**
   strcpy( *ptr, "Hello World");
}

int main()
{
   char *ptr = 0;
   // call function with a pointer to pointer
   foo( &ptr );
   printf("%s\n", ptr);
   // free up the memory
   free(ptr);

   return 0;
}
#包括
#包括
#包括
无效foo(字符**ptr)
{
*ptr=malloc(11);//分配一些内存
strcpy(*ptr,“你好世界”);
}
int main()
{
char*ptr=0;
//使用指向指针的指针调用函数
foo&ptr;
printf(“%s\n”,ptr);
//释放内存
免费(ptr);
返回0;
}
通过任意数字更改malloc…它始终在运行。这是如何实现的????
Hello World有12个字符,因此如何以0、12、8、任意数字运行。

您遇到了C不进行任何边界检查的事实。因此,您对malloc'd内存的复制过度运行了分配,并在随后的内存上“涂鸦”。结果未定义。它可能会工作,它可能会崩溃,它可能会给你一杯咖啡。你不知道


顺便说一句,这是一种导致缓冲区溢出攻击的错误。

您遇到了一个事实,即C不进行任何边界检查。因此,您对malloc'd内存的复制过度运行了分配,并在随后的内存上“涂鸦”。结果未定义。它可能会工作,它可能会崩溃,它可能会给你一杯咖啡。你不知道


顺便说一句,这是一种导致缓冲区溢出攻击的错误。

C不在乎您实际分配了多少(0除外;如果您这样做,事情可能会变得糟糕);只要你不超越各种任意的人为界限,你的程序就会(看起来)工作。你只是没有击中其中一个。

C不在乎你实际分配了多少(除了0;如果你这样做,事情会变得很糟糕);只要你不超越各种任意的人为界限,你的程序就会(看起来)工作。您只是没有击中其中一个。

通常的误解是,这样的错误一定会导致程序崩溃。事实上,C标准明确表示,对于此类未定义的行为,有“此国际标准不强制要求。”


因此,该程序可能会立即崩溃,可能会损坏随机数据,也可能看起来正常工作。就像Ed说的那样,这是不安全的。

人们普遍错误地认为这样的错误一定会导致程序崩溃。事实上,C标准明确表示,对于此类未定义的行为,有“此国际标准不强制要求。”


因此,该程序可能会立即崩溃,可能会损坏随机数据,也可能看起来正常工作。就像Ed说的那样,这是不安全的。

很明显,代码中有bug

有两种可能性:

  • 幸运的是,strcpy()没有命中任何重要的结果,因此程序运行

  • malloc()通常会比请求的多分配几个字节,以更好地保持内存对齐。例如,它完全可能以16个物理字节的块进行分配


  • 很明显,代码中有bug

    有两种可能性:

  • 幸运的是,strcpy()没有命中任何重要的结果,因此程序运行

  • malloc()通常会比请求的多分配几个字节,以更好地保持内存对齐。例如,它完全可能以16个物理字节的块进行分配


  • 根据定义,未定义的行为将以“意外”的方式进行操作。Strcpy不检查缓冲区长度。你在写不属于你的记忆。这就是语言的工作原理。这不安全。你必须小心。如果内存不是程序自己的,它不会马上崩溃吗?它可能会破坏程序使用的其他东西(调用堆栈等),我过去不得不调试行为非常不稳定的软件(随机崩溃等),结果证明这是在缓冲区上编写代码的一部分,并破坏程序使用的内存的其他部分。未定义的行为定义将在“意外”方式。Strcpy不检查缓冲区长度。您正在写入非您的内存。这是语言的工作方式。它不安全。您必须小心。如果内存不是程序的“自己的”,它不会立即崩溃吗?它可能会损坏程序使用的其他东西(调用堆栈等),我过去不得不调试行为非常不稳定的软件(随机崩溃等),结果证明这是在缓冲区上编写代码的一部分,并破坏了程序使用的内存的其他部分
    #include<stdio.h>
    #include<malloc.h>
    #include<string.h>
    
    void foo( char ** ptr)
    {
       *ptr = malloc(11); // allocate some memory
       strcpy( *ptr, "Hello World");
    }
    
    int main()
    {
       char *ptr = 0;
       // call function with a pointer to pointer
       foo( &ptr );
       printf("%s\n", ptr);
       // free up the memory
       free(ptr);
    
       return 0;
    }