如果 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++)
所以我有这个 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++)