Home > Software design >  How to stop a for loop and program if malloc returns nothing back
How to stop a for loop and program if malloc returns nothing back

Time:10-24

So I have this for loop where I allocate memory for each string in pointers array

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

If I check for the value of the malloc return in the for loop itself, my school compiler gives me some errors

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

How can I properly check if malloc returns a value and memory is actually allocated, in for loop?

Code:

#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;
}

The error :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 is located 0 bytes to the right of 13-byte region [0x6020000000d0,0x6020000000dd) allocated by thread T0 here: #0 0x563707584d77 in malloc (/work/main 0x94d77) #1 0x5637075c85a7 in main FINAL-FASTFOOD.c:53 #2 0x7fc505e0bcb1 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6 0x28cb1)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/work/main 0x380d9) in __interceptor_strcpy.part.0 Shadow bytes around the buggy address: 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 fa fa
0x0c047fff8030: fa fa 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 fa fa
0x0c047fff8050: fa fa 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 fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd
Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order:
f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal:
fe Left alloca redzone: ca Right alloca redzone: cb
Shadow gap: cc ==13==ABORTING

CodePudding user response:

The code in the question is inconsistent with the code in the program: you use a length of 14 bytes vs: 10 bytes in the program... Are you sure the error occurs for the posted code?

The allocation performed seems correct, but the comparison loop is incorrect as you compare the input before actually reading it. Furthermore you do not tell scanf() the maximum number of bytes to store into input, which can cause undefined behavior for long input words: this is a typical flaw attackers could use to try and execute arbitrary code.

Here is a modified version:

#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("ys", 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;
}

CodePudding user response:

check it with NULL

if (ptr[i] == null ){
    // do something
}
  • Related