Tag: 内存管理

为什么在堆栈中为局部变量分配的内存多于C ++中所需的内存?

我正在阅读缓冲区溢出。 我发现有关堆栈上局部变量的内存分配的一个奇怪的事情 int f1 () { char string1[12]; char string2[4]; } 这里分配发生在堆栈上。 现在,在GCC中, string2被分配了4个字节,但是如果我声明除了2的幂(最多16个)之外,那么它由编译器分配16个字节。 这意味着如果我在3,5,6,7,….,15个字节中分配string2,那么它由编译器分配16个字节,但如果我分配2的幂,如1,2,4,8 ……然后它被分配完全相同的大小。 如果我分配超过16个字节(不是2的幂),那么它分配32个字节(我估计高达32个字节)。 而在Visual Studio中,如果我分配1个字节,则分配9个字节,如果从2-4个字节分配,则分配12个字节,如果从5-8个字节开始,则编译器分配16个字节。 任何人都知道为什么这样的任务??? Atleast在Visual Studio中,如果有缓冲区溢出,我会收到调试错误,但在gcc中没有任何反应。 GCC仅在发生过大的溢出时才提供分段故障。

有效地存储三角矩阵

我需要通过不将所有零存储在内存中来有效地存储下三角矩阵,所以我已经考虑过这种方式:首先我为每一行分配内存,然后为每一行分配i + 1个字节,所以我永远不会不得不担心零,但在第一次分配时出现问题。 我究竟做错了什么? 这是我的代码,编译器在读取矩阵的维度后,在第8行退出程序。 #include #include int main () { int i, j, **mat1, dim; scanf(“%d”,&dim); *mat1 = (int**)calloc(dim, sizeof(int*)); for(i = 0; i<dim; i++) mat1[i] = (int*)calloc(i+1, sizeof(int)); for(i = 0; i < dim; i++) for(j = 0; j < i+1; j++) scanf("%d", &mat1[i][j]); for(i=0; i<dim; i++) for(j=0; j<(i+1); j++) printf("%d%c", mat1[i][j], j […]

`realloc`如何在后台实际工作?

realloc如何在后台实际工作? 如果在旧地方没有足够的可用内存,那么这个分配两个/多个内存块和一个指向该内存块的指针和其他指针在内部相互链接,或者旧区域被复制到新的位置,其中有足够的内存可用且指针正在更新到新地址并删除旧内存? 并且realloc是编译器/操作系统依赖还是独立 ?

我什么时候使用xdata?

我是嵌入式系统编程的新手。 我正在使用一个使用8051芯片组的设备。 我在示例程序中注意到,在定义变量时,有时它们使用关键字xdata。 像这样… static unsigned char xdata PatternSize; 而有时则省略xdata关键字。 我的理解是xdata关键字指示编译器将该变量存储在外部闪存存储器中。 在什么情况下我应该使用xdata在外部存储变量? 访问这些变量需要更长的时间,对吧? 使用xdata存储的值在设备硬重置后不会保留吗? 另外,我理解static关键字意味着变量将在每次调用它所定义的函数时持续存在。是否必须一起使用static和xdata?

什么可以解释对free()的调用堆腐败?

我已经调试了几天的崩溃,这发生在OpenSSL的深处(与维护者讨论)。 我花了一些时间进行调查,所以我会尝试让这个问题变得有趣且内容丰富。 首先,为了给出一些上下文,我重现崩溃的最小样本如下: #include #include #include #include #include #include int main() { ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); ENGINE_load_builtin_engines(); EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_sect571k1); EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED); EC_KEY* eckey = EC_KEY_new(); EC_KEY_set_group(eckey, group); EC_KEY_generate_key(eckey); BIO* out = BIO_new(BIO_s_file()); BIO_set_fp(out, stdout, BIO_NOCLOSE); PEM_write_bio_ECPrivateKey(out, eckey, NULL, NULL, 0, NULL, NULL); // <= CRASH. } 基本上,此代码生成椭圆曲线键并尝试将其输出到stdout 。 类似的代码可以在openssl.exe ecparam和Wikis online上找到。 它在Linux上运行正常(valgrind报告根本没有错误)。 它只在Windows上崩溃(Visual Studio 2013 […]

realloc失败的几率是多少?

当它耗尽类似于malloc的可用内存时,它是否会失败,还是有其他原因?

realloc但只有前几个字节才有意义

假设我使用过ptr = malloc(old_size); 使用old_size字节分配内存块。 只有第一个header_size字节才有意义。 我要将大小增加到new_size 。 new_size大于old_size , old_size大于header_size 。 之前: /- – – – – – – old_size – – – – – – – \ +===============+———————+ \-header_size-/ 后: /- – – – – – – – – – – – – – – new_size – – – – – – – – […]

C中的数组和指针有什么区别?

这个问题可能听起来很愚蠢,但我并不确定。 我的意思是,有什么区别: char* line = (char*) malloc(MAX_LINE_LEN); 和 char line[MAX_LINE_LEN]; 究竟? 我知道前者是一个指针而后者是一个数组,但系统如何区分呢? 如何分配/存储内存? 另外,为什么可以在声明为指针时删除line占用的内存,而不是当它是数组时? 我认为数组存储在其他地方,系统会在超出范围时自动释放内存,这在处理指针时不会发生,所以你必须自己删除它。 我错了吗?

将打包数据与对齐的内存访问相结合

我正在尝试执行一个理论上可行的内存优化,但我开始怀疑是arm-elf-gcc的能力。 请告诉我,我错了。 我有一个嵌入式系统,主内存非常少,电池支持的nvram数量更少。 我将校验和配置数据存储在nvram中,以便在启动时我可以validation校验和并继续先前的运行或在校验和无效时开始新的运行。 在运行期间,我在此配置数据中更新了各种大小的各种字段(并且可以使校验和无效,直到稍后重新计算)。 所有这些都在物理地址空间中运行 – 正常的sram映射在一个位置,nvram映射到另一个位置。 这是擦除 – 所有对nvram的访问必须以32位字进行; 不允许字节或半字访问(虽然它在主存中显然很好)。 因此,我可以a)将所有配置数据的工作副本存储在主存储器中,并在重新计算校验和时将其存储到nvram中或b)直接在nvram中使用它,但不知何故说服编译器所有结构都是打包和所有访问不仅必须是32位对齐 ,还必须是32 位宽 。 选项a)浪费宝贵的主存储器,我宁愿通过选项b)进行运行时权衡以保存它(尽管不是代码大小最终浪费的东西比我节省的数据大小更多)。 我希望__attribute__ ((packed, aligned(4)))或其中的一些变体可以在这里提供帮助,但到目前为止我所做的所有阅读和实验都让我失望了。 这是我正在处理的配置数据的玩具示例: #define __packed __attribute__ ((packed)) struct __packed Foo { uint64_t foo; struct FooFoo foofoo; } struct __packed Bar { uint32_t something; uint16_t somethingSmaller; uint8_t evenSmaller; } struct __packed PersistentData { struct Foo; struct Bar; /* […]

如何在C中进行自动内存管理?

在C内存分配/释放由malloc和free 。 在C ++内存分配/解除分配由new和delete 。 C ++中有一些用于自动内存管理的解决方案,例如: 智能指针。 RAII(资源获取初始化) 引用计数和循环引用 … 但是如何在C中进行自动内存管理? C中的AUTOMATIC内存管理有什么解决方案吗? 对于C,有没有任何指导或类似的指导? 我想要free一块内存: 我的代码没有编译 – 要么 – 内存自动解除分配 然后我说: 哦,C比C ++,Java和C#更好。 🙂