Код работает в Windows, но не в Linux! Зачем? [Простая проблема указателя] - PullRequest
2 голосов
/ 21 мая 2011

Это рабочий фрагмент кода проблемы с транспортировкой (Удалена реальная функция. Здесь присутствуют только функции ввода и вывода. И кстати, это неправильно)

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

typedef struct transport
{
    int cost;
    int alloc;
}TRAN;

void problem_input      (TRAN **, int *, int *, int, int);
void problem_display    (TRAN **, int *, int *, int, int);

int main()
{
    int n_dest;
    int n_org;
    int i;
    int j;

    printf("\n\n\tEnter Number Of Destinations          : ");
    scanf("%d", &n_dest);

    printf("\n\n\tEnter Number Of Origins(Sub-stations) : ");
    scanf("%d", &n_org);

    TRAN ** array   = (TRAN **)calloc(n_org, sizeof(TRAN *));

    int * dest      = (int *)calloc(n_dest, sizeof(int));
    int * origins   = (int *)calloc(n_org, sizeof(int));

    for(i = 0; i < n_org; i++)
    {
        array[i] = (TRAN *)calloc(n_dest, sizeof(TRAN *));
    }

    problem_input       (array, dest, origins, n_dest, n_org);
    problem_display     (array, dest, origins, n_dest, n_org);

    printf("\n\n");

    return 0;
}

void problem_input      (TRAN ** array, int * dest, int * origins, int n_dest, int n_org)
{
    int i;
    int j;

    printf("\n\n\tEnter The Amount Of Supplies Required At The Destinations : ");

    for(i = 0; i < n_dest; i++)
    {
        printf("\n\n\t\tDestination %d : ", (i+1));
        scanf("%d", &dest[i]);
    }

    printf("\n\n\tEnter The Amount Of Supplies Available At The Origins     : ");

    for(i = 0; i < n_org; i++)
    {
        printf("\n\n\t\tOrigin %d : ", (i+1));
        scanf("%d", &origins[i]);
    }

    printf("\n\n\tEnter The Cost Matrix : ");

    for(i = 0; i < n_org; i++)
    {
        printf("\n\n\t\tOrigin %d", (i+1));

        for(j = 0; j < n_dest; j++)
        {
            printf("\n\n\t\t\tDestination %d : ", (j+1));

            scanf("%d", &array[i][j].cost);
        }
    }
}

void problem_display    (TRAN ** array, int * dest, int * origins, int n_dest, int n_org)
{
    int i;
    int j;

    printf("\n\n\tThe Given Transportation Problem : ");

    for(i = 0; i < n_org; i++)
    {
        printf("\n\n\t");

        for(j = 0; j < n_dest; j++)
        {
            printf("\t%d", array[i][j].cost);
        }

        printf("\t[%d]", origins[i]);
    }

    printf("\n\n\t");

    for(i = 0; i < n_dest; i++)
    {
        printf("\t[%d]", dest[i]);
    }
}

В Windows это работало нормально, ноотображается неверный вывод в Linux.(Я использую Windows дома, но Linux в колледже. Представьте, что я чувствовал, когда получал неправильный вывод перед моим профессором. Но она не была мудрее.)

Например, мой вклад в «стоимость»'в TRAN ** array было

1 2 3
4 5 6
7 8 9

, но вывод был похож на

1 2 4
4 5 7
7 8 9

Моя ошибка была при создании структуры.Я создаю двумерные массивы, подобные этой (очень стандартный)

    TRAN ** array   = (TRAN **)calloc(n_org, sizeof(TRAN *));

    for(i = 0; i < n_org; i++)
    {
        array[i] = (TRAN *)calloc(n_dest, sizeof(TRAN));
    }

Но по ошибке я сделал это в цикле for

    for(i = 0; i < n_org; i++)
    {
        array[i] = (TRAN *)calloc(n_dest, sizeof(TRAN *));
    }

То есть sizeof(TRAN *) вместо sizeof(TRAN)

Итак, мой вопрос: почему эта явная ошибка не появилась в Windows?

Ответы [ 3 ]

1 голос
/ 21 мая 2011

Вероятно, что типы имеют разные размеры в разных операционных системах. Может оказаться, что в Windows sizeof (TRAN) == sizeof (TRAN *) (основано на элементах внутри TRAN и sizeof (int)), тогда как в Linux это явно не так.

0 голосов
/ 21 мая 2011

ОТМЕНА ОТВЕТА

Если вы посмотрите на свой код, вы не использовали компонент alloc.Теперь, когда вы выделяете структуру, она занимает 2n байт, где n - это размер целого числа.Вы получаете доступ только к компоненту cost.Также, потому что вы выделили TRAN * вместо TRAN при выполнении array[i][j], арифметический массив делает *(*(array + sizeof (int *)) + sizeof (TRAN *)), но вы хотели *(*(array + sizeof (int *)) + sizeof (TRAN)), когда в действительности вы получаете доступ к двум cost компонентам в двух структурах, которые онина самом деле доступны в соседних местах.Так что доступ к памяти совершенно правильный.потому что вы получаете доступ только к одному компоненту и читаете в том же месте, где вы написали с той же нотацией массива, так что вы получите тот же вывод, что и у ввода.Я предполагаю, что если вы напишите оба компонента alloc и cost, у вас будет сохранено только то значение, которое вы сохранили самое последнее для каждого i, j.

0 голосов
/ 21 мая 2011

Зависит от размера int от размера TRAN*.

Если вам «повезло» скомпилировать на 64-битной платформе с 32-битной int с, и у которой нет заполнения в struct TRAN, тогда sizeof(TRAN*) == sizeof(TRAN).

Если вы работаете на 32-битной платформе с 32-битной int с. Это больше не имеет места.

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