Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 运行时检查失败2-变量“obj”周围的堆栈已损坏_C_Buffer Overrun - Fatal编程技术网

C 运行时检查失败2-变量“obj”周围的堆栈已损坏

C 运行时检查失败2-变量“obj”周围的堆栈已损坏,c,buffer-overrun,C,Buffer Overrun,我得到运行时检查失败2-当我运行以下代码时,变量“obj”周围的堆栈已损坏错误。我知道这是失败的,因为覆盖了“obj”的边界导致堆栈损坏。那么如何防止缓冲区溢出呢 typedef struct _INFO { int Count; } Info, *InfoPtr; #define MAX_COUNT 10 //void fn(Info(*obj)[MAX_COUNT]) void fn(Info (*obj)[MAX_COUNT]) { for

我得到运行时检查失败2-当我运行以下代码时,变量“obj”周围的堆栈已损坏错误。我知道这是失败的,因为覆盖了“obj”的边界导致堆栈损坏。那么如何防止缓冲区溢出呢

typedef struct _INFO {
    int Count;
} Info, *InfoPtr;

#define MAX_COUNT               10

//void fn(Info(*obj)[MAX_COUNT])
void fn(Info (*obj)[MAX_COUNT])
{
    for (int i = 0; i < 2; i++) 
    {
        obj[i]->Count = i;
    }
}

int main()
{
    Info    obj[MAX_COUNT];
    fn(&obj);
    return 1;
}
使用Info*obj[MAX_COUNT]可以说obj是指向Info类型的MAX_COUNT对象数组的指针

但是,您可以像obj[i]->Count=i那样使用它,它将obj视为指向Info对象的指针数组。即信息*obj][]。不一样。这会导致未定义的行为

解决方案非常简单,不要将指向数组的指针作为参数传递,而是将其视为对象数组,而不是指向对象的指针

最显著的变化是fn函数声明,它使用指向Info的指针。这是因为数组自然会衰减到指向其第一个元素的指针。我还添加了一个参数来保存数组中的元素数,以便函数知道它。这使函数更通用,您可以传递不同大小的不同数组

我还改为main函数,根本不返回任何内容。由于C99标准,没有显式返回的主函数将由编译器隐式获取返回0。从主函数返回0通常被视为正常或无故障。返回非零值被视为失败或错误

我还更改了您的结构的名称。编译器和标准C库在所有作用域中都保留名称C或预处理器(带前导下划线和大写字母)。此外,结构标记名位于单独的命名空间中,因此您可以使用与类型名类型别名相同的结构名,如typedef所定义。我还删除了InfoPtr类型名,使用类型名之类的指针会混淆代码,降低代码的可读性和可维护性。

对于Info*obj[MAX\u COUNT],您说obj是指向Info类型的MAX\u COUNT对象数组的指针

但是,您可以像obj[i]->Count=i那样使用它,它将obj视为指向Info对象的指针数组。即信息*obj][]。不一样。这会导致未定义的行为

解决方案非常简单,不要将指向数组的指针作为参数传递,而是将其视为对象数组,而不是指向对象的指针

最显著的变化是fn函数声明,它使用指向Info的指针。这是因为数组自然会衰减到指向其第一个元素的指针。我还添加了一个参数来保存数组中的元素数,以便函数知道它。这使函数更通用,您可以传递不同大小的不同数组

我还改为main函数,根本不返回任何内容。由于C99标准,没有显式返回的主函数将由编译器隐式获取返回0。从主函数返回0通常被视为正常或无故障。返回非零值被视为失败或错误

我还更改了您的结构的名称。编译器和标准C库在所有作用域中都保留名称C或预处理器(带前导下划线和大写字母)。此外,结构标记名位于单独的命名空间中,因此您可以使用与类型名类型别名相同的结构名,如typedef所定义。我还删除了InfoPtr类型名,使用类型名之类的指针会混淆代码,降低代码的可读性和可维护性。

更改此信息*obj[MAX\u COUNT]->size\u t size,Info obj[size]。系统会“保留”后跟大写字母的下划线序列,因此,不应在用户代码中使用此类序列。请更改此Info*obj[MAX\u COUNT]->size\t size,Info obj[size]。系统会保留后跟大写字母的序列下划线,因此不应在用户代码中使用此类序列。
typedef struct Info {
    int Count;
} Info;

#define MAX_COUNT               10

void fn(Info *obj, const size_t elems)
{
    for (size_t i = 0; i < elems; i++) 
    {
        obj[i].Count = i;
    }
}

int main()
{
    Info    obj[MAX_COUNT];
    fn(obj, MAX_COUNT);
}