#include <stdio.h> #include <stdlib.h> int main() { char * chr = (char*)malloc(sizeof(char)); chr = "apple"; printf("%s", chr); return 0; }
你好。我有个关于马洛克的问题。我只做了int大小的字节(1byte)与malloc。我输入超大的字母“苹果”(6字节),我以为输出会像“A”或“A”。但产出的却是“苹果”。这怎么可能?
m1m5dgzv1#
内存malloc赋值的方式与声明变量或数组时的内存赋值方式不同。Malloc(及其派生)在声明一个字符串或一个int在堆栈中分配内存时,在堆中分配内存。
char *ptr = malloc(sizeof(char) * (elem + 1)); // Here malloc is called, memory is assined in the heap ptr = "hello world"; // allocates a new space in the stach where the string hello world is stored
基本上,这里你没有用apple填充内存的分配空间。您正在删除一个包含apple的新文件。如果你是C编程新手,我建议你在使用malloc之前先学习如何使用指针和数组(尝试复制strlen,puts或其他类似的简单函数)
apple
有什么区别?不同的是,当你的程序运行时,你的堆栈内存会改变当你的主函数被加载时,它会加载堆栈中的变量。然后,当您调用其他函数(如f1)时,f1及其变量也将加载到堆栈中下面是一个例子:
int f1() { int var4 = 0; // step 2 and 5 return (0); } char *f2() { int var5 = 0; int var6 = 0; char *f2_ptr = malloc(sizeof(char) * 10); // we will ignore this for the first part // step 4 f1() // step 6 return (ptr); } int main(void) { int var1 = 0; int var2 = 0; int var3 = 0; // step 1 f1(); // step 3 char *main_ptr = f2() // step 7 free(ptr) // step 8 (only for Stack + Heap part) return (0); }
有你记忆中的shema一步一步
步骤1 main和我们变量已经加载
main var1 var2 var3
第二步我们已经输入了f1,main和main的变量仍然在这里,但是现在我们也有了f1和f1变量
main var1 var2 var3 f1 var4
步骤3我们已经离开了f1,所以它已经被卸载。main和我们的主变量仍然加载
第4步就像在第2步中我们已经进入了一个函数(f2),main和我们的main的变量仍然存在,我们加载f2和f2变量
main var1 var2 var3 f2 var5 var6
第5步我们再次进入F1。f1及其变量加载在堆栈底部
main var1 var2 var3 f2 var5 var6 f1 var4
第6步,我们离开f1,f1及其变量被卸载
第7步,我们离开f2,f2及其变量被卸载
正如你所看到的,我们在程序中进展得越多,我们在堆栈中的位置就越低。当我们碰到一个return语句时,我们回到栈中。
当你使用malloc时,内存返回的分配空间不存储在堆栈中。这允许你有一个内存段,当你离开函数时,它不会被卸载。这允许你做动态内存分配和很多其他的事情。下面是使用malloc的一步一步的例子:步骤1、2和3基本上与第一部分相同
步骤4这次我们使用malloc,从堆栈中分配一个新的内存段。其地址存储在f2_ptr中
main var1 var2 var3 main_ptr f2 var5 var6 f2_ptr malloc_memory_segment
步骤5正如你所看到的,由malloc创建的内存段仍然位于内存的底部。
main var1 var2 var3 main_ptr f2 var5 var6 f2_ptr f1 var4 malloc_memory_segment
第7步,我们留下f2,f2和它的变量是unload,但不是malloc分配的段
main var1 var2 var3 main_ptr malloc_memory_segment
步骤8我们释放main_ptr,它删除malloc_memory_segment
main var1 var2 var3 main_ptr
希望这足够清楚,它可以帮助您了解程序是如何工作的祝你好运,继续学习
i86rm4rw2#
chr = "apple";
重写存储在chr本身中的指针。在此之后,当probram被加载时,在某处分配的字符串"apple"被使用,而不是通过malloc()分配的缓冲区。这个操作是安全的,只泄漏一小块内存。要通过执行超出范围的写入来调用危险的 * 未定义行为 *,您可以像这样使用strcpy():
chr
"apple"
malloc()
strcpy()
strcpy(chr, "apple");
2条答案
按热度按时间m1m5dgzv1#
内存malloc赋值的方式与声明变量或数组时的内存赋值方式不同。
Malloc(及其派生)在声明一个字符串或一个int在堆栈中分配内存时,在堆中分配内存。
基本上,这里你没有用
apple
填充内存的分配空间。您正在删除一个包含apple
的新文件。如果你是C编程新手,我建议你在使用malloc之前先学习如何使用指针和数组(尝试复制strlen,puts或其他类似的简单函数)
下一部分仅在您想大致了解其工作原理时才会出现
有什么区别?
不同的是,当你的程序运行时,你的堆栈内存会改变当你的主函数被加载时,它会加载堆栈中的变量。然后,当您调用其他函数(如f1)时,f1及其变量也将加载到堆栈中
下面是一个例子:
有你记忆中的shema一步一步
仅堆栈
步骤1 main和我们变量已经加载
第二步我们已经输入了f1,main和main的变量仍然在这里,但是现在我们也有了f1和f1变量
步骤3我们已经离开了f1,所以它已经被卸载。main和我们的主变量仍然加载
第4步就像在第2步中我们已经进入了一个函数(f2),main和我们的main的变量仍然存在,我们加载f2和f2变量
第5步我们再次进入F1。f1及其变量加载在堆栈底部
第6步,我们离开f1,f1及其变量被卸载
第7步,我们离开f2,f2及其变量被卸载
正如你所看到的,我们在程序中进展得越多,我们在堆栈中的位置就越低。当我们碰到一个return语句时,我们回到栈中。
堆栈+堆
当你使用malloc时,内存返回的分配空间不存储在堆栈中。这允许你有一个内存段,当你离开函数时,它不会被卸载。这允许你做动态内存分配和很多其他的事情。
下面是使用malloc的一步一步的例子:
步骤1、2和3基本上与第一部分相同
步骤4这次我们使用malloc,从堆栈中分配一个新的内存段。其地址存储在f2_ptr中
步骤5正如你所看到的,由malloc创建的内存段仍然位于内存的底部。
第6步,我们离开f1,f1及其变量被卸载
第7步,我们留下f2,f2和它的变量是unload,但不是malloc分配的段
步骤8我们释放main_ptr,它删除malloc_memory_segment
希望这足够清楚,它可以帮助您了解程序是如何工作的
祝你好运,继续学习
i86rm4rw2#
重写存储在
chr
本身中的指针。在此之后,当probram被加载时,在某处分配的字符串"apple"
被使用,而不是通过malloc()
分配的缓冲区。这个操作是安全的,只泄漏一小块内存。要通过执行超出范围的写入来调用危险的 * 未定义行为 *,您可以像这样使用
strcpy()
: