如果 malloc returns 没有返回,如何停止 for 循环和程序

How to stop a for loop and program if malloc returns nothing back

所以我有这个 for 循环,我在其中为指针数组中的每个字符串分配内存

for (int i = 0; i < N; ++i) {
    ptr[i] = malloc(14 * sizeof(char));
}

如果我在 for 循环本身中检查 malloc return 的值,我的学校编译器会给我一些错误

    for (int i = 0; i < N; ++i) {
        ptr[i] = malloc(14 * sizeof(char));
        if (!ptr[i]) {
            fprintf(stderr, "Out of memory!\n");
            exit(-10);
        } 
    }

如何在 for 循环中正确检查 malloc return 是否实际分配了一个值和内存?

代码:

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

#define N  2

int main(void) {
    char **ptr;
    ptr = (char **)malloc(N * (sizeof(char *)));
    if (!ptr) {
        fprintf(stderr, "Out of memory!\n");
        exit(-10);
    }
    char *hamburger = "hamburger";
    char *icecream = "icecream";

    for (int i = 0; i < N; ++i) {
        ptr[i] = malloc(10 * sizeof(char));
        if (!ptr[i]) {
            fprintf(stderr, "Out of memory!\n");
            exit(-10);
        }
    }

    strcpy(ptr[0], hamburger);
    strcpy(ptr[1], icecream);
    char *end = "pay";
    char input[80] = "";
    int price = 0;
    while (!str_compare(input, end)) {
        scanf("%s", input);
        if (str_compare(ptr[0], input))
            price += 150;
        if (str_compare(ptr[1], input))
            price += 40;
    }
    printf("Total price %d", price);

    for (int i = 0; i < N; i++) {
        free(ptr[i]);
    }

    free(ptr);
    ptr = NULL;
    hamburger = NULL;
    icecream = NULL;
 
    end = NULL;
    return 0;
}

错误:D

================================================================= ==13==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000000dd at pc 0x5637075280da bp 0x7ffc25536920 sp 0x7ffc255360c8 WRITE of size 14 at 0x6020000000dd thread T0 #0 0x5637075280d9 in __interceptor_strcpy.part.0 (/work/main+0x380d9) #1 0x5637075c8836 in main FINAL-FASTFOOD.c:69 #2 0x7fc505e0bcb1 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x28cb1) #3 0x5637074f843d in _start (/work/main+0x843d)

0x6020000000dd 位于 13 字节区域右侧的 0 字节处 [0x6020000000d0,0x6020000000dd) 在这里由线程 T0 分配: #0 0x563707584d77 在 malloc (/work/main+0x94d77) #1 0x5637075c85a7 in main FINAL-FASTFOOD.c:53 #2 __libc_start_main 中的 0x7fc505e0bcb1 (/lib/x86_64-linux-gnu/libc.so.6+0x28cb1)

摘要:AddressSanitizer:堆缓冲区溢出(/work/main+0x380d9) 在 __interceptor_strcpy.part.0 越野车地址周围的影子字节: 0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff8000: fa fa 00 05 fa fa 00 05 fa fa 00 05 fa fa 00 05 => 0x0c047fff8010:fa fa 00 05 fa fa 00 05 fa fa 00[05]fa fa fa fa 0x0c047fff8020:fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa 阴影 字节图例(一个影子字节代表8个应用字节):
可寻址:00 部分可寻址:01 02 03 04 05 06 07 堆左 redzone:fa 释放堆区域:fd
Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after 范围:f8 全局 redzone:f9 全局初始化顺序:
f6 用户中毒:f7 容器溢出:fc 数组 cookie: ac Intra object redzone: bb ASan internal:
fe 左 alloca redzone: ca 右 alloca redzone: cb
阴影间隙:cc ==13==中止

问题中的代码与程序中的代码不一致:你使用的长度是14字节vs:程序中的10字节...你确定贴出的代码有错误吗?

执行的分配似乎是正确的,但是当您比较输入 之前 实际读取它时,比较循环是不正确的。此外,您没有告诉 scanf() 要存储到 input 中的最大字节数,这可能会导致长输入单词出现未定义的行为:这是攻击者可以用来尝试执行任意代码的典型缺陷。

这是修改后的版本:

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

#define N  2

bool str_compare(const char *s1, const char *s2) {
    return !strcmp(s1, s2);
}

int main(void) {
    char **ptr;
    ptr = malloc(N * (sizeof(char *)));
    if (!ptr) {
        fprintf(stderr, "Out of memory!\n");
        exit(-10);
    }
    const char *hamburger = "hamburger";
    const char *icecream = "icecream";

    for (int i = 0; i < N; ++i) {
        ptr[i] = malloc(10 * sizeof(char));
        if (!ptr[i]) {
            fprintf(stderr, "Out of memory!\n");
            exit(-10);
        }
    }

    strcpy(ptr[0], hamburger);
    strcpy(ptr[1], icecream);

    const char *end = "pay";
    char input[80];
    int price = 0;
    while (scanf("%79s", input) == 1 && !str_compare(input, end)) {
        if (str_compare(ptr[0], input))
            price += 150;
        else
        if (str_compare(ptr[1], input))
            price += 40;
        else
            printf("unknown item: %s\n", input);
    }
    printf("Total price %d\n", price);

    for (int i = 0; i < N; i++) {
        free(ptr[i]);
    }
    free(ptr);

    return 0;
}

您正在分配 2 * char 指针,但是 for 循环正在分配 3 次。上次分配内存的时候发生了啊缓冲区溢出,因为你没有分配3 * char Pointers

尝试像这样更改 for 循环:

For(int i=0; i <= N; i++)