malloc: проверка ошибок и освобождение памяти - PullRequest
1 голос
/ 04 апреля 2010

Я использую malloc, чтобы проверить, можно ли выделить память для определенного массива z1. ARRAY_SIZE является предопределенным с числовым значением. Я использую кастинг, так как прочитал, что это безопасно.

long double *z1 = (long double *)malloc(sizeof (long double) * ARRAY_SIZE);  
if(z1 == NULL){  
   printf("Out of memory\n");  
   exit(-1);  
}

Выше приведен фрагмент моего кода, но когда я добавляю часть проверки ошибок (содержащуюся в приведенном выше операторе if), я получаю много ошибок времени компиляции в Visual Studio 2008. Именно эта часть проверки ошибок генерирует все ошибки. Что я делаю не так?

Что касается связанной с malloc проблемы, я понимаю, что память должна быть освобождена / освобождена после использования переменной / массива z1. Для массива z1 я использую:

free(z1);
z1 = NULL;

Нужна ли вторая строка z1 = NULL?

Я получаю 102 ошибки ... ну, MVS2008 останавливает ошибки на 102. Ошибки имеют тип:

error C2143: syntax error : missing ';' before 'type'  
error C2065: 'L' : undeclared identifier
// this error repeats for all my identifiers

и это указывает сразу после закрытия} в операторе if.

ARRAY_SIZE довольно большой. Я определяю это как

#define ARRAY_SIZE 2500001

Мой полный приведенный выше код слишком длинный. Но у меня есть меньший код, который дает мне такое же поведение. Извините за форматирование. Я не могу понять это правильно.

#include stdio.h //note I have the actual < > in my code
#include stdlib.h
#include math.h
#define ARRAY_SIZE 11
#define VECTOR_SIZE 5

main()
{
    long double *z = (long double*) malloc(sizeof (long double) * ARRAY_SIZE);
    if(z == NULL){
        printf("Out of memory\n");
        exit(-1);
    }

    long double *k = (long double*) malloc(sizeof (long double) * VECTOR_SIZE);
    int i;
    long double A, B;
    void f(long double fa[], long double fb[], long double fA, long double fB);

    A = 0.5;
    B = 2;

    for(i = 0; i < VECTOR_SIZE; i++){
        k[i] = 0;
    }

    k[1] = 4;
    k[2] = 8;

    for(i = 0; i < ARRAY_SIZE; i++){
        z[i] = 0;
    }

    z[1] = 5;


    f(k, z, A, B);

    free(z);
    free(k);
    z = NULL;
    k = NULL;
}


void f(fa, fb, fA, fB)
long double fa[], fb[], fA, fB;
{
    fa[0] = fb[1]* fA;
    fa[1] = fa[1] - 1;
    fb[0] = 2* fB - fa[2];
    printf("fa[2] is 8 and is the same as *[fa + 2] and is  %3.3Le\n", *(fa + 2));
    printf("\nAddress of &fa[2] is %x\n", &fa[2]);
    printf("same address is fa + 2 is %x\n", fa + 2);
    return;
}

Ответы [ 3 ]

3 голосов
/ 04 апреля 2010

Проблемы в вашем коде

Allright. Теперь, когда вы предоставили весь код, вам легче объяснить ваши проблемы:

  1. Вы пытаетесь определить переменные "в середине" ваших функций. C не позволяет это . Вы должны определить все свои переменные в самом начале. Вот что дает вам
    error C2143: syntax error : missing ';' before 'type'
    ошибки.
  2. То же самое относится и к объявлению функции (должно быть вверху функции).

Следовательно, изменение вашего кода на следующее заставляет его работать:

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

#define ARRAY_SIZE 11
#define VECTOR_SIZE 5

main() {
    void f(long double fa[], long double fb[], long double fA, long double fB);

    long double* z = (long double*) malloc(sizeof (long double) * ARRAY_SIZE);
    long double* k = (long double*) malloc(sizeof (long double) * VECTOR_SIZE);
    int i;
    long double A, B;

    if (z == NULL) {
        printf("Out of memory\n");
        exit(-1);
    }

    A = 0.5;
    B = 2;

    for (i = 0; i < VECTOR_SIZE; i++) {
        k[i] = 0;
    }

    k[1] = 4;
    k[2] = 8;

    for (i = 0; i < ARRAY_SIZE; i++) {
        z[i] = 0;
    }

    z[1] = 5;

    f(k, z, A, B);

    free(z);
    free(k);
    z = NULL;
    k = NULL;
}

void f(fa, fb, fA, fB)  
long double fa[], fb[], fA, fB;  
{
    fa[0] = fb[1]* fA;
    fa[1] = fa[1] - 1;
    fb[0] = 2* fB - fa[2];

    printf("fa[2] is 8 and is the same as *[fa + 2] and is  %3.3Le\n", *(fa + 2));
    printf("\nAddress of &fa[2] is %x\n", &fa[2]);
    printf("same address is fa + 2 is %x\n", fa + 2);

    return;
}


Несколько других пунктов

Теперь я добавлю еще несколько советов, которые, возможно, не являются строго ошибками (имеется в виду, что они все еще компилируются ...), но не являются очень хорошими методами кодирования:

  1. Как я уже говорил, используйте const с для определения констант, а не #define с.
  2. правильно определите main() - то есть int main() {..., а не просто main() без типа возврата. Это работает в C, но не работает в C ++, и я считаю это плохим стилем. (Какого черта я должен предполагать, что функции возвращают int, если ничего не сказано? Почему бы не void?)
  3. После этого вы должны явно вернуть значение из main().
  4. Я предпочитаю объявлять прототип функции void f(long double fa[], long double fb[], long double fA, long double fB); за пределами main().
  5. При определении функций используйте современный синтаксис, который вы использовали в прототипе, а не древний:
    void f(fa, fb, fA, fB)
    long double fa[], fb[], fA, fB;
    {
    Должно стать:
    void f(long double fa[], long double fb[], long double fA, long double fB) {.

Таким образом, ваш код превращается в:

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

void f(long double fa[], long double fb[], long double fA, long double fB);

int main() {
    const int ARRAY_SIZE = 11;
    const int VECTOR_SIZE = 5;

    long double* z = (long double*) malloc(sizeof (long double) * ARRAY_SIZE);
    long double* k = (long double*) malloc(sizeof (long double) * VECTOR_SIZE);

    int i;
    long double A, B;

    if (z == NULL) {
        printf("Out of memory\n");
        exit(-1);
    }

    A = 0.5;
    B = 2;

    for (i = 0; i < VECTOR_SIZE; i++) {
        k[i] = 0;
    }

    k[1] = 4;
    k[2] = 8;

    for (i = 0; i < ARRAY_SIZE; i++) {
        z[i] = 0;
    }

    z[1] = 5;

    f(k, z, A, B);

    free(z);
    free(k);
    z = NULL;
    k = NULL;

    return 0;
}

void f(long double fa[], long double fb[], long double fA, long double fB) {
    fa[0] = fb[1]* fA;
    fa[1] = fa[1] - 1;
    fb[0] = 2* fB - fa[2];

    printf("fa[2] is 8 and is the same as *[fa + 2] and is  %3.3Le\n", *(fa + 2));
    printf("\nAddress of &fa[2] is %x\n", &fa[2]);
    printf("same address is fa + 2 is %x\n", fa + 2);

    return;
}  

Что мне кажется лучше.


Первое сообщение

Пожалуйста, предоставьте весь свой код. Я тестировал следующий код в Visual C ++ 2008 Express с отключенными «языковыми расширениями» и предупреждениями 4 уровня. Работает просто отлично:

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

int main() {
    const int ARRAY_SIZE = 1024*1024;

    long double *z1 = (long double *)malloc(sizeof (long double) * ARRAY_SIZE);
    if (z1 == NULL) {
        printf("Out of memory\r\n");
        exit(-1);
    }

    printf("Awesome!\r\n");

    return 0;
}

Может быть, вы забыли включить, может, вы сделали что-то еще не так. Сам фрагмент кода выглядит совершенно нормально. Вторая ошибка, которую вы описали, кажется совершенно не связанной: error C2065: 'L' : undeclared identifier // this error repeats for all my identifiers

Кстати, предпочитайте const, а не #define.

1 голос
/ 04 апреля 2010

Попробуйте # include-ing stdio.h и stdlib.h, чтобы убедиться, что NULL действительно определен.

И для ответа на ваш второй вопрос установка z1 в значение NULL не обязательна, хотя это поможет вам убедиться, что вы никогда не попытаетесь случайно использовать z1 после его освобождения, поскольку разыменование нулевого указателя приведет к сбою. Так что это хорошая оборонительная вещь, но не обязательная.

0 голосов
/ 04 апреля 2010

Возможно, вам придется проверить в других местах вашего кода, если выделено z1. Установка NULL - хороший способ сказать, что память не выделена для указателя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...