简体   繁体   English

当我访问超出我分配的内存时,为什么我没有得到堆栈粉碎错误?

[英]Why am I not getting stack smashing error when I access memory beyond what I allocated?

I should get stack smashing error here . 我应该在这里得到堆栈粉碎错误。 What is the reason I am not getting it? 我没有得到它的原因是什么?

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

struct mun
{
    int len;
    char str[0];

};

int main(void)
{

    //char mp[8];
    struct mun *p=malloc(sizeof(struct mun)+2);
    p->len=8;
    strcpy(p->str,"munjalllfff");
    //strcpy(mp,"munjalllfff");

    printf("%s\n",p->str);
    //printf("%s\n",mp);

    return 0;
}

Please explain if possible or (a topic name or link will enough for me.) 如果可能请解释或(主题名称或链接对我来说足够了。)

Most C implementations won't bother to protect the stack or heap from being overwritten by a few bytes only. 大多数C实现都不会费心保护堆栈或堆只被几个字节覆盖。 (There's a library aptly named Electric Fence that can do so). (有一个名为Electric Fence的图书馆,可以这样做)。 Chances are, if you write enough data, you'll eventually write beyond the allowed address space and the program crashes in one way or another (this depends on many factors, like OS, compiler, options). 有可能,如果你写了足够的数据,你最终会写出超出允许的地址空间,程序会以某种方式崩溃(这取决于许多因素,如操作系统,编译器,选项)。 As you noticed by now, this answer is very vague. 正如你现在所注意到的,这个答案非常模糊。 The reason is that what you do is technically called undefined behavior by the C Standard, which means the implementation is free to do anything, including nothing. 原因是你所做的是技术上被C标准称为未定义的行为 ,这意味着实现可以自由地做任何事情,包括什么都不做。

Why is it so? 为什么会这样? Why doesn't the C Standard have a clause saying 为什么C标准没有条款说

3.1.4.1.5 When an access outside of allocated memory is attempted, a statement equivalent to fprintf(stderr, "illegal access at %p\\n", (void *)address); 3.1.4.1.5当尝试在分配的内存之外进行访问时,等同于fprintf(stderr, "illegal access at %p\\n", (void *)address);的语句fprintf(stderr, "illegal access at %p\\n", (void *)address); shall be executed. 应执行。

The reason is that this would place a heavy burden on the implementation. 原因是这会给实施带来沉重的负担。 The compiler probably would have to generate code to check for illegal accesses after almost all pointer modifications and function calls. 在几乎所有指针修改和函数调用之后,编译器可能必须生成代码来检查非法访问。 C is, by design, a tiny language where programmers get mostly what they ask for and no "invisible code" in addition. 在设计上,C是一种微小的语言,程序员主要得到他们所要求的东西,而且没有“隐形代码”。

And then, stderr may be closed or non-existent :-) 然后, stderr可能已关闭或不存在:-)

You're invoking undefined behavior. 您正在调用未定义的行为。 Anything could happen. 什么事情都可能发生。 If you're lucky it will crash, if you're unlucky it will sign you up for Google+. 如果你很幸运,它会崩溃,如果你运气不好,它会为你注册Google+。

这不在堆栈上,使用free(p),你可能会看到一些错误!

This is clearly Undefined behavior . 这显然是未定义的行为 It may work and may not! 它可能工作,可能不会!

To avoid it you should use strncpy() while copying the string. 为了避免它,你应该在复制字符串时使用strncpy()

strncpy(p->str,"munjalllfff",sizeof(p->str));

Also don't forget to free() the memory you have allocated using malloc() . 另外,不要忘记使用malloc() free()已分配的malloc()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM