2014-03-13 9 views
0

我正在玩一些cpp的基本东西。我是这种语言的新手......所以我警告说我的问题可能没有正确制定。我感谢任何帮助。此代码似乎追加分配范围以外的字符

的事情是,看到后的例子在www.cplusplus.com/reference/cstdlib/malloc/我发现我自己使用此代码:

#include <stdio.h> 

int main (void) { 
    char *str; 
    str = (char*) malloc(2); 
    str[0] ='8'; 
    str[1] ='8'; 
    str[2] ='6'; 
    str[3] ='\0'; 
    printf ("%s\n",str); 
} 

并与编译:

gcc -O0 -pedantic -Wall test2.cpp 

(gcc版本4.7.2)

我没有得到任何错误和输出886.为什么我没有得到任何错误?我没有通过分配空间的边界吗?

我没有得到任何错误,我得到了输出886.为什么没有错误?我没有通过分配空间的边界吗?

在代码没问题的情况下......为什么参考中的例子? 在另一个(更可能)的情况下......有什么风险?

谢谢!

+0

任何像样的静态分析工具(例如cppcheck)都应该告诉你(我想即使是Eclipse CDT C++ SA解析器也可以)。 –

+0

谢谢。离C++很远吗?主要区别是什么?新手如何区分彼此? (用fortran我花了几年的时间才知道sintax来自每个版本) – alexis

+0

最简单的线索是使用'malloc'和'printf'。大多数C++代码使用'new'和'cout'。 –

回答

5

您不会收到任何错误,因为C和C++不会执行边界检查。你重写了你没有使用的记忆部分,但你很幸运,这并不重要。比较一下,把一排钉子钉在墙上,你知道有一个钉子。如果你错过了双头螺栓,大部分时间,你只需在石膏上放一个孔,但这样做很危险,因为最终你会碰到其中一条电​​线。

3

您已经越过了分配内存的边界。

但是,printf并不会打扰您声明的内存大小。所有它关心的是它将从一开始就开始并继续,直到它找到0.

您创建的情况是未定义的行为。在您分配的区域(也许是另一个变量)之后可能会有其他一些数据,在这种情况下它会被损坏。如果下一部分是未分配的内存,则可能会出现没有可见问题的情况。如果分配内存后的内存属于另一个进程,您将看到很好且整齐的分段错误。后果可能更糟,所以最好不要在任何地方尝试。

+0

非常感谢!非常快速的答案!伟大的论坛,伟大的用户。 – alexis

1

以下可以在注释中找到glibc中的malloc.c:

每分配块

最小开销:4或8个字节每个malloced 块具有开销保持尺寸和状态信息 的隐藏字。

最小分配的大小:4字节师生比:16个字节(包括4 开销) 8字节师生比:24/32字节(包括,4/8开销)

当块被释放,12 (对于4字节)或20(对于8字节
ptrs但是4字节大小)或24(对于8/8)额外字节是需要的; 4(8)为尾部大小字段,8(16)字节为空闲列表 指针。因此,最小可分配大小是16/24/32字节。

由于最小分配大小为16/24/32,因为它大于3个字节,程序无错地运行。这是正确执行程序的可能性之一。

+1

这是所有可能实现的一个(!) - 具有微小内存的嵌入式系统的malloc可能会精确分配请求的内存(仅此而已) –

+0

@DieterLücking是的,这是可能的实现之一,我相信他遇到了这个malloc的一种实现。 – Balu

+1

谢谢。这也有帮助。其实我会寻求任何帮助,而且我总是学习。 – alexis