预期时未收到段错误 [英] Not receiving a seg fault when expected

查看:17
本文介绍了预期时未收到段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习如何在 C 中使用指针和结构.当然,我试图故意破坏我的代码以进一步了解该语言的工作原理.下面是一些测试代码,可以按我的预期工作:

I'm in the process of learning how to use pointers and structs in C. Naturally, I'm trying to deliberately break my code to further understand how the language works. Here is some test code that works as I expected it to work:

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

struct pair {
    int x;
    int y;
};

typedef struct pair pair;

void p_struct( pair ); //prototype

int main( int argc, char** argv ) {
    pair *s_pair;
    int size, i;

    printf( "Enter the number of pair to make: " );
    scanf( "%d", &size );
    getchar();
    printf( "
" );

    s_pair = (pair*)malloc( size * sizeof(pair) );

    for( i = 0; i < size; i++ ) {
        s_pair[i].x = i;
        s_pair[i].y = i;
        p_struct( s_pair[i] );
    }

    getchar();

    return (EXIT_SUCCESS);
}

void p_struct( pair s_pair ) {
    printf( "
%d %d
", s_pair.x, s_pair.y );
}

如前所述,据我所知,这段代码是有效的.

As previously stated, this code is functional as far as I can tell.

然后我决定像这样修改部分代码:

I then decided to modify a part of the code like so:

for( i = 0; i < size + 3; i++ ) {
    s_pair[i].x = i;
    s_pair[i].y = i;
    p_struct( s_pair[i] );
}

此修改没有产生我预期的 seg 错误错误.尽管我超出了使用 scanf 函数为变量 size 赋值时明确设置的缓冲区,但所有对"都被打印出来了.

This modification did not produce the seg fault error that I expected it would. All of the "pairs" were printed despite me exceeding the buffer I explicitly set when assigning a value to my variable size using the scanf function.

据我了解指针(如果我错了,请纠正我),当我调用malloc 函数用于我的类型对 s_pair 的指针.我所做的是,当我将 for 循环修改为条件 i < 时,我超出了最后分配的内存地址.大小 + 3.

As I understand pointers (correct me if I'm wrong), a contiguous block of memory of size size*sizeof(pair) is reserved by the memory manager in the heap when I called the malloc function for my pointer of type pair s_pair. What I did was I exceeded the last assigned address of memory when I modified my for loop to the condition i < size + 3.

如果我理解正确的话,我的指针是否超出了它的保留内存限制,并且恰好是清晰的,因为它的右侧和附近没有被其他数据占用?这是溢出缓冲区时的正常行为吗?

If I'm understanding this correctly, did my pointer exceed its reserved memory limit and just so happen to be in the clear because nothing adjacent and to the right of it was occupied by other data? Is this normal behaviour when overflowing a buffer?

补充一点,当我使用 i < 的 for 循环条件进行测试时,我确实收到了 seg 错误.大小 + 15.问题是,它仍然打印输出.如,当 size = 10 根据我制作的 p_struct 函数在屏幕上打印时,它会在屏幕上打印0 0"对24 24".程序只有在到达底部的 getchar() 之一后才会因段错误而崩溃.我的程序究竟如何将值分配给超出缓冲区的对,将它们打印在屏幕上,然后突然决定在到达 getchar() 时因段错误而崩溃?i < 似乎没有问题.size + 3(尽管它仍然是错误的).

To add, I did receive a seg fault when I tested with a for loop condition of i < size + 15. The thing is, it still prints the output. As in, it prints the pair "0 0" to pair "24 24" when size = 10 on the screen as per the p_struct function I made. The program crashes by seg fault only after it gets to one of those getchar()s at the bottom. How on earth could my program assign values to pairs that exceed the buffer, print them on the screen, and then all of a sudden decide to crash on seg fault when it gets to getchar()? It seemed to have no issue with i < size + 3 (despite it still being wrong).

作为记录,我还使用常规指针数组测试了这种行为:

For the record, I also tested this behaviour with a regular pointer array:

int size, i, *ptr;

scanf( "%d", &size );

ptr = (int*)malloc( size * sizeof(int) );

for( i = 0; i < size + 15; i++ )
    ptr[i] = i;

这会产生与上面完全相同的结果.在 我 <size + 3 段错误似乎没有任何问题.

This produces the exact same result as above. At i < size + 3 there doesn't seem to be any issue with seg faults.

最后,我也用数组进行了测试:

Finally, I tested with an array, too:

int i, array[10];

for( i = 0; i < 25; i++ )
    array[i] = i;

对于条件 i <25,我得到了一个段错误,没有失败.当我将其更改为 i <15,我没有收到 seg 错误.

For the condition i < 25, I get a seg fault without fail. When I change it to i < 15, I receive no seg fault.

如果我没记错的话,指针数组和数组之间的唯一区别是分配给数组的内存位于堆栈而不是堆上(对此不确定).考虑到这一点,并考虑到 i <15array[10] 不产生任何 seg 错误时,为什么 i <25 是个问题吗?在 for 循环期间,数组不是位于堆栈顶部吗?当它不关心 60 个额外字节时,为什么它会关心 100 个额外字节?为什么该数组缓冲区的上限不是一直到为整个堆栈保留的任意内存块的末尾?

If I remember correctly, the only difference between an array of pointers and an array is that the memory allocated to an array is located on the stack as opposed to the heap (not sure about this). With that in mind, and considering the fact that i < 15 when array[10] doesn't produce any seg faults, why would i < 25 be an issue? Isn't the array at the top of the stack during that for loop? Why would it care about 100 extra bytes when it didn't care about 60 extra bytes? Why isn't the ceiling for that array buffer all the way to the end of whatever arbitrary chunk of memory is reserved for the whole stack?

希望所有这些对于决定阅读一个稍微醉酒的人的漫谈的人来说都是有意义的.

Hopefully all of this made sense to whoever decides to read a slightly inebriated man's ramblings.

推荐答案

欢迎来到辉煌的C语言世界!

Welcome to the glorious world of C!

内存分配函数(malloccallocrealloc 等)为您提供堆上的内存.当您调用其中一个并且您的程序没有足够的空间时,它会进行 系统调用获得更多.但是,它不会以精确的增量执行此操作(它通常会以某些数量的整页增量执行此操作).当您在数组末尾(或什至在数组开头之前)进行索引时,您仍在程序的合法地址空间范围内.只有当您离开您的程序拥有的分段时,您才会收到分段违规.

The memory allocation functions (malloc, calloc, realloc, etc) give you memory that's on the heap. When you call one of them and your program doesn't have enough space, it makes a system call to get more. It doesn't do this in precise increments though (it often will do so in some number of whole page increments). When you're indexing past the end of your array (or even before the beginning of it) you are still within the bounds of your program's legal address space. Only when you leave the segment your program owns will you get a Segmentation Violation.

我强烈建议使用 Valgrind 来检查您的程序,尤其是当您故意尝试通过破坏来了解内存时.除其他外,它将在分配的任一侧存储金丝雀值,以帮助您确定何时访问越界并警告您双重释放和内存泄漏.

I highly recommend using Valgrind to inspect your program, especially if you are deliberately trying to learn about memory by breaking things. Among other things, it will store canary values on either side of allocations to help you figure out when you're accessing out of bounds and warn you about double frees and memory leaks.

这篇关于预期时未收到段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆