2015-10-31 2 views
0

Minimally Verifiable Source Code - I think. Я пытаюсь использовать динамическое выделение массива указателей в функции для создания двойного массива двойных указателей. Когда я использую код вне ссылки на структуру, он работает. Когда я пытаюсь ссылаться на него с помощью указателя, это не так. Что я делаю не так?динамическое выделение несоответствия массива указателей в GCC

Этот код работает в GCC 4.9.2

gcc -v 
Using built-in specs. 
COLLECT_GCC=gcc 
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper 
Target: x86_64-linux-gnu 
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.9.2-10ubuntu13' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu 
Thread model: posix 
int main(int argc, char **argv) 
{ 
    double ** array; 
    double row[6] = { 1.2, 2.3, 3.0, 4, 5, 6 }; 
    int i; 
    int j; 
    array = (double **) malloc(50* sizeof(double * ) ); 
    for (i = 0; i < 50; i++) 
    { 
     array[i] = (double *) malloc(6 * sizeof(double ) ); 
    } 
    for (j =0; j < 50; j++) 
    for (i = 0; i < 6; i++) 
    { 
     array[j][i] = row[i]; 
    } 
    for (j =0; j < 50; j++) 
    { 
     for (i = 0; i < 6; i++) 
     { 
      printf("%f ", (array[0][i])); 
     } 
     printf("\n "); 
    } 
    exit(0); // Use exit() to exit a program, do not use 'return' from main() 
} 

Но этот код не будет:

double ** create_array(unsigned int length, unsigned int row) 
{ 
    double ** array; 
    int i; 

    array = (double **) malloc(length * sizeof(double * ) ); 
    for (i = 0; i < length; i++) 
    { 
     array[i] = (double *) malloc(row * sizeof(double ) ); 
    } 
    return array; 
} 

Я поместил двойной массив двойной указатель внутри структуры

typedef struct 
{ 
     // the data area 
    double ** array; 
    // the number of rows in the entire entry 
    unsigned int length; 
    // the size of the double entity of array size 
    unsigned int rowsize; 
    // the current starting point 
    int start; 
    // the current ending point 
    int end; 
    // the amount of the last write action 
    // assumes the number of write in order 
    unsigned int last_write[100]; 
    // the number of writes 
    unsigned int write_count; 
} DRingBuffer; 

А затем получить доступ через следующие вызовы функций, как это:

int DRingBuffer_printrow(DRingBuffer *buffer, unsigned int row ) 

Когда я вызываю функцию, а затем попытаться получить доступ к членам его SEG недостатков.

 printf("%f ", (buffer->array[3][2])); 

Это много кода, но кто-то его попросил.

DRingBuffer *DRingBuffer_create(unsigned int length, unsigned int row ) 
    { 
     int i =0; 
     DRingBuffer *buffer = malloc(sizeof(DRingBuffer)); 
     buffer->length = length; 
     buffer->rowsize = row; 
     buffer->start = 0; 
     buffer->end = 0; 
     buffer->array = create_array( length, row); 
     if (buffer->array <= 0 ) 
     { 
      printf("ERROR: allocating arrays"); 
      exit(-1); 
     } 
     return buffer; 
    } 
+2

Как инициализируется 'buffer'? – ouah

+1

Как вы называете функцию 'create_buffer'? Как вы инициализируете структуру 'DRingBuffer'? –

+1

О, и в C [вы не должны накладывать результат 'malloc'] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) (или любую другую функцию возвращающий 'void *'). –

ответ

0

Вместо того, чтобы выделить массив указателей на другие массивы, чтобы реализовать 2D массива, который вы должны просто создать единое выделение, а затем доступ к нему, как array[x + y*WIDTH]. Это более эффективно, менее подвержены ошибкам и т.д.

Ваш код будет тогда проще:

double * create_array(unsigned int length, unsigned int row) 
{ 
    return malloc(length * row * sizeof(double)); 
} 

и функцию в() может выглядеть следующим образом:

// return element at row column 
double at(double * array, unsigned int row, unsigned int col, unsigned int width) 
{ 
      return array[ col + row * width ]; 
} 
+0

Но тогда я не могу использовать [] [] ссылку. Таким образом, моя ошибка переместится в указатель add math ...;) – daemondave

+1

@daemondave Вы не можете использовать [] [], но вы можете создать функцию в (row, col), которая читается (или больше), и делает необходимый расчет , Отдельные распределения для каждой строки бесполезно неэффективны. – user4815162342

+0

Итак, как бы выглядела функция(). Я понимаю, что я не совсем эффективен, но по сравнению с C++ это достаточно эффективно. Кроме того, это не мое время, и я больше человек философии в Unix, я не кодирую все это часто и не возвращаюсь к коду, чтобы понять, что я написал. Поэтому, если это более эффективно и легко понять отлично. Оптимизация - это не мое внимание, но я не против. – daemondave

0

Ваш код в create_array() должно быть хорошо. Он работает нормально для меня. Вы не показываете код, в котором вы его используете, поэтому мы не можем быть уверены, как вы злоупотребляете им, но кажется, что вы.

Вот адаптация кода:

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

static 
double **create_array(unsigned int length, unsigned int row) 
{ 
    double **array; 

    array = (double **) malloc(length * sizeof(double *)); 
    for (unsigned int i = 0; i < length; i++) 
    { 
     array[i] = (double *) malloc(row * sizeof(double)); 
    } 
    return array; 
} 

int main(void) 
{ 
    double **array; 
    double row[6] = { 1.2, 2.3, 3.0, 4, 5, 6 }; 

    array = (double **) malloc(50 * sizeof(double *)); 
    for (int i = 0; i < 50; i++) 
    { 
     array[i] = (double *) malloc(6 * sizeof(double)); 
    } 

    for (int j = 0; j < 50; j++) 
    { 
     for (int i = 0; i < 6; i++) 
     { 
      array[j][i] = row[i] + (i + 1) * (j + 1); 
     } 
    } 
    for (int j = 0; j < 50; j++) 
    { 
     for (int i = 0; i < 6; i++) 
     { 
      printf("%6.1f ", (array[j][i])); 
     } 
     putchar('\n'); 
    } 

    for (int j = 0; j < 50; j++) 
     free(array[j]); 
    free(array); 

    double **array2 = create_array(50, 6); 

    for (int j = 0; j < 50; j++) 
    { 
     for (int i = 0; i < 6; i++) 
     { 
      array2[j][i] = row[i] + (i + 1) * (j + 1); 
     } 
    } 
    for (int j = 0; j < 50; j++) 
    { 
     for (int i = 0; i < 6; i++) 
     { 
      printf("%6.1f ", (array2[j][i])); 
     } 
     putchar('\n'); 
    } 

    for (int j = 0; j < 50; j++) 
     free(array2[j]); 
    free(array2); 

    return(0); 
} 

Проверено на Mac OS X 10.11.1 El Capitan, он производит:

2.2 4.3 6.0 8.0 10.0 12.0 
    3.2 6.3 9.0 12.0 15.0 18.0 
    4.2 8.3 12.0 16.0 20.0 24.0 
    5.2 10.3 15.0 20.0 25.0 30.0 
    6.2 12.3 18.0 24.0 30.0 36.0 
    7.2 14.3 21.0 28.0 35.0 42.0 
    8.2 16.3 24.0 32.0 40.0 48.0 
    9.2 18.3 27.0 36.0 45.0 54.0 
    10.2 20.3 30.0 40.0 50.0 60.0 
    11.2 22.3 33.0 44.0 55.0 66.0 
    12.2 24.3 36.0 48.0 60.0 72.0 
    13.2 26.3 39.0 52.0 65.0 78.0 
    14.2 28.3 42.0 56.0 70.0 84.0 
    15.2 30.3 45.0 60.0 75.0 90.0 
    16.2 32.3 48.0 64.0 80.0 96.0 
    17.2 34.3 51.0 68.0 85.0 102.0 
    18.2 36.3 54.0 72.0 90.0 108.0 
    19.2 38.3 57.0 76.0 95.0 114.0 
    20.2 40.3 60.0 80.0 100.0 120.0 
    21.2 42.3 63.0 84.0 105.0 126.0 
    22.2 44.3 66.0 88.0 110.0 132.0 
    23.2 46.3 69.0 92.0 115.0 138.0 
    24.2 48.3 72.0 96.0 120.0 144.0 
    25.2 50.3 75.0 100.0 125.0 150.0 
    26.2 52.3 78.0 104.0 130.0 156.0 
    27.2 54.3 81.0 108.0 135.0 162.0 
    28.2 56.3 84.0 112.0 140.0 168.0 
    29.2 58.3 87.0 116.0 145.0 174.0 
    30.2 60.3 90.0 120.0 150.0 180.0 
    31.2 62.3 93.0 124.0 155.0 186.0 
    32.2 64.3 96.0 128.0 160.0 192.0 
    33.2 66.3 99.0 132.0 165.0 198.0 
    34.2 68.3 102.0 136.0 170.0 204.0 
    35.2 70.3 105.0 140.0 175.0 210.0 
    36.2 72.3 108.0 144.0 180.0 216.0 
    37.2 74.3 111.0 148.0 185.0 222.0 
    38.2 76.3 114.0 152.0 190.0 228.0 
    39.2 78.3 117.0 156.0 195.0 234.0 
    40.2 80.3 120.0 160.0 200.0 240.0 
    41.2 82.3 123.0 164.0 205.0 246.0 
    42.2 84.3 126.0 168.0 210.0 252.0 
    43.2 86.3 129.0 172.0 215.0 258.0 
    44.2 88.3 132.0 176.0 220.0 264.0 
    45.2 90.3 135.0 180.0 225.0 270.0 
    46.2 92.3 138.0 184.0 230.0 276.0 
    47.2 94.3 141.0 188.0 235.0 282.0 
    48.2 96.3 144.0 192.0 240.0 288.0 
    49.2 98.3 147.0 196.0 245.0 294.0 
    50.2 100.3 150.0 200.0 250.0 300.0 
    51.2 102.3 153.0 204.0 255.0 306.0 
    2.2 4.3 6.0 8.0 10.0 12.0 
    3.2 6.3 9.0 12.0 15.0 18.0 
    4.2 8.3 12.0 16.0 20.0 24.0 
    5.2 10.3 15.0 20.0 25.0 30.0 
    6.2 12.3 18.0 24.0 30.0 36.0 
    7.2 14.3 21.0 28.0 35.0 42.0 
    8.2 16.3 24.0 32.0 40.0 48.0 
    9.2 18.3 27.0 36.0 45.0 54.0 
    10.2 20.3 30.0 40.0 50.0 60.0 
    11.2 22.3 33.0 44.0 55.0 66.0 
    12.2 24.3 36.0 48.0 60.0 72.0 
    13.2 26.3 39.0 52.0 65.0 78.0 
    14.2 28.3 42.0 56.0 70.0 84.0 
    15.2 30.3 45.0 60.0 75.0 90.0 
    16.2 32.3 48.0 64.0 80.0 96.0 
    17.2 34.3 51.0 68.0 85.0 102.0 
    18.2 36.3 54.0 72.0 90.0 108.0 
    19.2 38.3 57.0 76.0 95.0 114.0 
    20.2 40.3 60.0 80.0 100.0 120.0 
    21.2 42.3 63.0 84.0 105.0 126.0 
    22.2 44.3 66.0 88.0 110.0 132.0 
    23.2 46.3 69.0 92.0 115.0 138.0 
    24.2 48.3 72.0 96.0 120.0 144.0 
    25.2 50.3 75.0 100.0 125.0 150.0 
    26.2 52.3 78.0 104.0 130.0 156.0 
    27.2 54.3 81.0 108.0 135.0 162.0 
    28.2 56.3 84.0 112.0 140.0 168.0 
    29.2 58.3 87.0 116.0 145.0 174.0 
    30.2 60.3 90.0 120.0 150.0 180.0 
    31.2 62.3 93.0 124.0 155.0 186.0 
    32.2 64.3 96.0 128.0 160.0 192.0 
    33.2 66.3 99.0 132.0 165.0 198.0 
    34.2 68.3 102.0 136.0 170.0 204.0 
    35.2 70.3 105.0 140.0 175.0 210.0 
    36.2 72.3 108.0 144.0 180.0 216.0 
    37.2 74.3 111.0 148.0 185.0 222.0 
    38.2 76.3 114.0 152.0 190.0 228.0 
    39.2 78.3 117.0 156.0 195.0 234.0 
    40.2 80.3 120.0 160.0 200.0 240.0 
    41.2 82.3 123.0 164.0 205.0 246.0 
    42.2 84.3 126.0 168.0 210.0 252.0 
    43.2 86.3 129.0 172.0 215.0 258.0 
    44.2 88.3 132.0 176.0 220.0 264.0 
    45.2 90.3 135.0 180.0 225.0 270.0 
    46.2 92.3 138.0 184.0 230.0 276.0 
    47.2 94.3 141.0 188.0 235.0 282.0 
    48.2 96.3 144.0 192.0 240.0 288.0 
    49.2 98.3 147.0 196.0 245.0 294.0 
    50.2 100.3 150.0 200.0 250.0 300.0 
    51.2 102.3 153.0 204.0 255.0 306.0 

Он также не попадала любую память, или шоу любые нарушения памяти при запуске под valgrind. Или, по крайней мере, на El Capitan, утечки памяти - все из системного кода, полностью вне контроля над такими смертными, как вы и я.

Будут те, кто вас избивает (и, вероятно, меня тоже), для литья результата malloc(). Помните о своей чувствительности и будьте осторожны. Если вы собираете с таким строгими предупреждениями компиляции, как я использую, вы не столкнетесь с проблемами:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \ 
>  -Wold-style-definition -Werror ddda.c -o ddda 
$ 
+0

Интересно, что произойдет, если вы скомпилируете эти флаги без сбоев? Почему он не будет работать на ubuntu? Я обращаю ваше внимание на typecast malloc. Я взял их, но это не было причиной. О последний вопрос, какая версия GCC? Возможно, это разрешено в версии? – daemondave

+0

Удаление параметров предупреждения не влияет на результат. Он компилируется без предупреждений с помощью '-std = c99', и он работает нормально. При компиляции с '-std = c90' компилятор (правильно) жалуется на обозначения' for (int i = 0; ...) '. Замените все те, что были 'int i; int j; 'вверху и удалить' int' из элементов управления контуром, и он компилируется чисто и работает под '-std = c90'. Я фактически использовал «gcc», который поставляется с XCode 7.1 («Apple LLVM version 7.0.0 (clang-700.1.76)»), но я также использовал GCC 5.2.0. Одно из преимуществ компиляции - это то, что код работает без проблем. –

+0

Вы скопировали код из моего ответа дословно и скомпилировали его? Неужели это тебе не удалось? –

0

выхода из пробеге DDDA.c по ubuntu:

> gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes 
> -Wstrict-prototypes -Wold-style-definition -Werror -o working working.c [email protected]:/home/home/dave/src/ringbuffer/src$ ./working 
> 2.2 4.3 6.0 8.0 10.0 12.0 
> 3.2 6.3 9.0 12.0 15.0 18.0 
> 4.2 8.3 12.0 16.0 20.0 24.0 
> 5.2 10.3 15.0 20.0 25.0 30.0 
> 6.2 12.3 18.0 24.0 30.0 36.0 
> 7.2 14.3 21.0 28.0 35.0 42.0 
> 8.2 16.3 24.0 32.0 40.0 48.0 
> 9.2 18.3 27.0 36.0 45.0 54.0 
> 10.2 20.3 30.0 40.0 50.0 60.0 
> 11.2 22.3 33.0 44.0 55.0 66.0 
> 12.2 24.3 36.0 48.0 60.0 72.0 
> 13.2 26.3 39.0 52.0 65.0 78.0 
> 14.2 28.3 42.0 56.0 70.0 84.0 
> 15.2 30.3 45.0 60.0 75.0 90.0 
> 16.2 32.3 48.0 64.0 80.0 96.0 
> 17.2 34.3 51.0 68.0 85.0 102.0 
> 18.2 36.3 54.0 72.0 90.0 108.0 
> 19.2 38.3 57.0 76.0 95.0 114.0 
> 20.2 40.3 60.0 80.0 100.0 120.0 
> 21.2 42.3 63.0 84.0 105.0 126.0 
> 22.2 44.3 66.0 88.0 110.0 132.0 
> 23.2 46.3 69.0 92.0 115.0 138.0 
> 24.2 48.3 72.0 96.0 120.0 144.0 
> 25.2 50.3 75.0 100.0 125.0 150.0 
> 26.2 52.3 78.0 104.0 130.0 156.0 
> 27.2 54.3 81.0 108.0 135.0 162.0 
> 28.2 56.3 84.0 112.0 140.0 168.0 
> 29.2 58.3 87.0 116.0 145.0 174.0 
> 30.2 60.3 90.0 120.0 150.0 180.0 
> 31.2 62.3 93.0 124.0 155.0 186.0 
> 32.2 64.3 96.0 128.0 160.0 192.0 
> 33.2 66.3 99.0 132.0 165.0 198.0 
> 34.2 68.3 102.0 136.0 170.0 204.0 
> 35.2 70.3 105.0 140.0 175.0 210.0 
> 36.2 72.3 108.0 144.0 180.0 216.0 
> 37.2 74.3 111.0 148.0 185.0 222.0 
> 38.2 76.3 114.0 152.0 190.0 228.0 
> 39.2 78.3 117.0 156.0 195.0 234.0 
> 40.2 80.3 120.0 160.0 200.0 240.0 
> 41.2 82.3 123.0 164.0 205.0 246.0 
> 42.2 84.3 126.0 168.0 210.0 252.0 
> 43.2 86.3 129.0 172.0 215.0 258.0 
> 44.2 88.3 132.0 176.0 220.0 264.0 
> 45.2 90.3 135.0 180.0 225.0 270.0 
> 46.2 92.3 138.0 184.0 230.0 276.0 
> 47.2 94.3 141.0 188.0 235.0 282.0 
> 48.2 96.3 144.0 192.0 240.0 288.0 
> 49.2 98.3 147.0 196.0 245.0 294.0 
> 50.2 100.3 150.0 200.0 250.0 300.0 
> 51.2 102.3 153.0 204.0 255.0 306.0 
> 2.2 4.3 6.0 8.0 10.0 12.0 
> 3.2 6.3 9.0 12.0 15.0 18.0 
> 4.2 8.3 12.0 16.0 20.0 24.0 
> 5.2 10.3 15.0 20.0 25.0 30.0 
> 6.2 12.3 18.0 24.0 30.0 36.0 
> 7.2 14.3 21.0 28.0 35.0 42.0 
> 8.2 16.3 24.0 32.0 40.0 48.0 
> 9.2 18.3 27.0 36.0 45.0 54.0 
> 10.2 20.3 30.0 40.0 50.0 60.0 
> 11.2 22.3 33.0 44.0 55.0 66.0 
> 12.2 24.3 36.0 48.0 60.0 72.0 
> 13.2 26.3 39.0 52.0 65.0 78.0 
> 14.2 28.3 42.0 56.0 70.0 84.0 
> 15.2 30.3 45.0 60.0 75.0 90.0 
> 16.2 32.3 48.0 64.0 80.0 96.0 
> 17.2 34.3 51.0 68.0 85.0 102.0 
> 18.2 36.3 54.0 72.0 90.0 108.0 
> 19.2 38.3 57.0 76.0 95.0 114.0 
> 20.2 40.3 60.0 80.0 100.0 120.0 
> 21.2 42.3 63.0 84.0 105.0 126.0 
> 22.2 44.3 66.0 88.0 110.0 132.0 
> 23.2 46.3 69.0 92.0 115.0 138.0 
> 24.2 48.3 72.0 96.0 120.0 144.0 
> 25.2 50.3 75.0 100.0 125.0 150.0 
> 26.2 52.3 78.0 104.0 130.0 156.0 
> 27.2 54.3 81.0 108.0 135.0 162.0 
> 28.2 56.3 84.0 112.0 140.0 168.0 
> 29.2 58.3 87.0 116.0 145.0 174.0 
> 30.2 60.3 90.0 120.0 150.0 180.0 
> 31.2 62.3 93.0 124.0 155.0 186.0 
> 32.2 64.3 96.0 128.0 160.0 192.0 
> 33.2 66.3 99.0 132.0 165.0 198.0 
> 34.2 68.3 102.0 136.0 170.0 204.0 
> 35.2 70.3 105.0 140.0 175.0 210.0 
> 36.2 72.3 108.0 144.0 180.0 216.0 
> 37.2 74.3 111.0 148.0 185.0 222.0 
> 38.2 76.3 114.0 152.0 190.0 228.0 
> 39.2 78.3 117.0 156.0 195.0 234.0 
> 40.2 80.3 120.0 160.0 200.0 240.0 
> 41.2 82.3 123.0 164.0 205.0 246.0 
> 42.2 84.3 126.0 168.0 210.0 252.0 
> 43.2 86.3 129.0 172.0 215.0 258.0 
> 44.2 88.3 132.0 176.0 220.0 264.0 
> 45.2 90.3 135.0 180.0 225.0 270.0 
> 46.2 92.3 138.0 184.0 230.0 276.0 
> 47.2 94.3 141.0 188.0 235.0 282.0 
> 48.2 96.3 144.0 192.0 240.0 288.0 
> 49.2 98.3 147.0 196.0 245.0 294.0 
> 50.2 100.3 150.0 200.0 250.0 300.0 
> 51.2 102.3 153.0 204.0 255.0 306.0 

Он работает с этими наборами CFLAGS. Так что да, ваш измененный код действительно сработал. Я сейчас нахожусь в недоумении относительно того, насколько единственными отличиями являются установленные флаги.

Смежные вопросы