сбой при печати %p

#c #pointers #segmentation-fault #printf

#c #указатели #ошибка сегментации #printf

Вопрос:

         printf("nframe is: %p",amp;frame);
        printf("nframeprev is: %p",amp;framePrev);
  

какая бы строка ни была первой, она всегда будет правильно напечатана.
Вторая строка всегда будет иметь ошибку сегментации в приведенном выше коде, независимо от того, какой указатель она выводит. есть идеи, почему это происходит? Я пробовал fflush ( стандартный вывод); после каждого printf, но это, похоже, не имеет никакого значения.

указатель удаляется с помощью следующего

 frame =(double**) malloc(cols*sizeof(double));
framePrev =(double**) malloc(cols*sizeof(double));

if(frame==NULL||framePrev==NULL){
    printf("malloc epic failn");
    return 0;
}

/*allocate mem for 2nd dimention*/

for(i=0;i<cols;i  ){
    frame[i]=(double*) malloc(rows*sizeof(double));
    framePrev[i]=(double*) malloc(rows*sizeof(double));
    /*check for null pointer*/
    if(frame[i]==NULL||framePrev[i]==NULL){
        printf("malloc epic failn");
        return 0;
    }
}
  

Комментарии:

1. Попробуйте отладчик, подобный gdb или инструмент отладки памяти, подобный valgrind . Вероятно, они очень быстро покажут, где именно вы нарушаете сегментацию.

2. Вы хотите сказать, что функции printf() следуют за основным кодом?

3. Файлы printf находятся в верхней части цикла for, который выполняется после mallocs, но при первом выполнении цикла он сообщает о сбое сегмента между двумя файлами printf — так что, возможно, это просто сбой сегмента после и printf медленный, я не слишком уверен

4. frame N is: 0xbffff368 Program received signal SIGSEGV, Segmentation fault. это результат, который я получаю, и я обычно ожидаю, что второй оператор будет напечатан ниже

Ответ №1:

Я не знаю, почему тот код, который вы предоставили, приведет к segfault. Однако то, что вы пытаетесь распечатать, — это адрес указателя, а не содержимое указателя. Другими словами, frame — это переменная-указатель; она имеет размер 4 байта и находится где-то в стеке / куче. Вы распечатываете адрес этого где-то. Я думаю, вы хотите напечатать значение frame; которое было бы фактическим указателем, содержащимся в этом фрейме. Итак, уберите amp; в каждой строке и посмотрите, что вы получите.

Кроме того, у вас странное распределение памяти. A (double **) — это указатель на массив, который содержит указатели на удвоения; но ваш вызов malloc выделяет массив, который содержит удвоения. Вероятно, вам нужен malloc(cols * sizeof(double *)). Этот код работает, потому что double больше, чем double *, поэтому вы фактически выделяете достаточно памяти, но это все равно неправильно.

Комментарии:

1. Да, это ошибка, должно быть double * при распределении для перехода от указателя к указателю. Неудивительно, что это приводит к сбою.

Ответ №2:

В ваших инструкциях printf нет ничего неправильного. Если вы нарушаете сегментацию, это, вероятно, потому, что у вас ошибка в ваших подпрограммах и у вас разбита память.

Одна из очевидных проблем в том, что вы опубликовали, заключается в том, что ваши массивы frame и frameprev являются не массивами double, а двойными указателями, и маловероятно, что они имеют одинаковый размер. Первые две строки должны быть:

 frame =(double**) malloc(cols*sizeof(double *));
framePrev =(double**) malloc(cols*sizeof(double *));
  

Комментарии:

1. Значение float обычно помещается в регистр, например, является длиной собственного int, например, размером указателя. Удвоение действительно длиннее.

Ответ №3:

просто поместите код в test.cpp файл, подобный этому:

 int main(){

    int i, cols=4, rows=2;
    double **frame =(double**) malloc(cols*sizeof(double));
    double **framePrev =(double**) malloc(cols*sizeof(double));

    if(frame==NULL||framePrev==NULL){
        printf("malloc epic failn");
        return 0;
    }

    /*allocate mem for 2nd dimention*/
    for(i=0;i<cols;i  ){
        frame[i]=(double*) malloc(rows*sizeof(double));
        framePrev[i]=(double*) malloc(rows*sizeof(double));
        /*check for null pointer*/
        if(frame[i]==NULL||framePrev[i]==NULL){
            printf("malloc epic failn");
            return 0;
        }
    }

    printf("nframe is: %p",amp;frame);
    printf("nframeprev is: %p",amp;framePrev);
}
  

скомпилирован с помощью g test.cpp , запустите его через ./a.out ->

 frame is: 0x7fff5fbffaf8
frameprev is: 0x7fff5fbffaf0
  

нарушения сегментации вообще нет.

как вам скомпилировать? какие-либо другие изменения в вашем коде теперь показаны в вашем сообщении? как вы инициализируете свои переменные?

правила.

Комментарии:

1. спасибо за помощь, ребята, это действительно помогло, вы, ребята, были правы, этот код был в порядке, это была следующая строка, вызывающая проблемы, она просто помешала окончательной печати попасть на терминал (doh! — моя ошибка).