1

Тема: Перевірка виділення пам'яті

Була функція:

struct TreeNode *insert(struct TreeNode* rootPtr, int data) {
    if (rootPtr == NULL)
    {
        rootPtr = (struct TreeNode *)malloc(sizeof(struct TreeNode));
        rootPtr->value = data;
        rootPtr->left = NULL;
        rootPtr->right = NULL;
    }
    else if (data < rootPtr->value) {
        rootPtr->left = insert(rootPtr->left, data);
    }
    else {
        rootPtr->right = insert(rootPtr->right, data);
    }
    return rootPtr;
}

Викладач сказав, що потрібно перевіряти malloc, чи поверенула вона вказівник NULL:

struct TreeNode *insert(struct TreeNode* rootPtr, int data) {
    if (rootPtr == NULL)
    {
        if (!(rootPtr = (struct TreeNode *)malloc(sizeof(struct TreeNode)))) {
            printf("Error: can't allocate memory");
            EXIT_FAILURE;
        }
        else {
            rootPtr->value = data;
            rootPtr->left = NULL;
            rootPtr->right = NULL;
        }
    }
    else if (data < rootPtr->value) {
        rootPtr->left = insert(rootPtr->left, data);
    }
    else {
        rootPtr->right = insert(rootPtr->right, data);
    }
    return rootPtr;
}

Невпевненний чи правильно я написав чи ні. Як можно перевірити ?

2

Re: Перевірка виділення пам'яті

Як перевірити - не знаю. Але зазвичай EXIT_FAILURE - то 1 чи -1, тобто у вас цей рядок виглядає як

1;

Думаю, викладач не це мав на увазі, а хоча б

exit(EXIT_FAILURE);
Подякували: laketych, Chemist-i2

3

Re: Перевірка виділення пам'яті

Якщо malloc не змогла виділити блок пам'яті, то повертається nullptr. Починаючи з С++11, вказівник який == nullptr також == NULL. Тому можна так:

rootPtr = (struct TreeNode *)malloc(sizeof(struct TreeNode));
if(rootPtr == NULL)
{
      // пам'ять не виділена - вихід з помилкою або throw
}
else
{
      ...
}

Наступні вирази еквівалентні:

rootPtr == nullptr
rootPtr == NULL
rootPtr == 0
!rootPtr

Однак якщо мова йде про вказівник, то краще використовувати nullptr, тому що різниця все-таки є. Ось приклад:

void foo(int) 
{ 
     cout << "foo(int)" << endl; 
}
void foo(char*) 
{ 
     cout << "foo(char*)" << endl; 
}

int main()
{
     char* с = NULL;
     foo(с);        // викликається foo(char*)
     foo(NULL);     // викликається foo(int)
     foo(nullptr);  // викликається foo(char*)
     return 0;
}
Подякували: Kaskade1

4

Re: Перевірка виділення пам'яті

Пане LoganRoss, а до чого тут взагалі C++? Ну виразно ж pure C, по застосуванню struct видно.

Подякували: LoganRoss1

5

Re: Перевірка виділення пам'яті

koala написав:

Пане LoganRoss, а до чого тут взагалі C++? Ну виразно ж pure C, по застосуванню struct видно.

Але це не виключає, що це не може бути С++. Згідний, що struct і malloc - це С, але вони часто застосовуються і в С++ проектах як суржики.
Нехай автор скаже С чи С++.

Подякували: koala1

6

Re: Перевірка виділення пам'яті

LoganRoss написав:

Однак якщо мова йде про вказівник, то краще використовувати nullptr, тому що різниця все-таки є. Ось приклад:

     foo(NULL);     // викликається foo(int)
     foo(nullptr);    // викликається foo(char*)

Залежить від.
Може бути #define NULL ((void*)0), тоді з foo(int) і foo(char*) ще й нічого вибрати, invalid conversion по обох шляхах кандидатів.
g++ має щось внутрішнє #define NULL __null, у результаті error: call of overloaded ‘foo(NULL)’ is ambiguous, але будь-яка одна функція з foo(int) і foo(char*) підійде.

А з nullptr весело стане, коли буде  foo(int*) і foo(char*) ;)

7

Re: Перевірка виділення пам'яті

Якщо для С, то можна так (але можна й скоротити код):

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

int        main(void)
{
    typedef struct        s_list
    {
        void            *content;
        size_t            content_size;
        struct s_list    *next;
    }                    t_list;

    t_list *list;

    list = (t_list*)malloc(sizeof(t_list));
    if (!list)
        exit(write(2, "Error: can't allocate memory\n", 29));
    /*
    ** code
    */
    printf("all good, memory allocated\n");
    free(list);
    return (0);
}

І тут буде два випадки: або malloc зробить свою роботу та виділить пам'ять, або поверне NULL