Oracle Pro*C Segmentation fault (ядрото е изхвърлено)

Обучавам се на Pro*C и това е програма с курсор през записи в база данни, която се компилира и изпълнява. Стига се до подкана „Въведете Guest_ID (напишете изход за прекратяване)>>“. След това дава грешка като „Грешка на сегментиране (ядрото е изхвърлено)“, ако е въведено цяло число. Ако се въведе низ, изглежда, че той отива в условния елемент непосредствено във външния for цикъл на

if(nGuest_ID==0)
{
      printf("BYE\n");
      exit(0);
}

и отпечатва "BYE", след което излиза. Тъй като все още се запознавам с това как променливите се декларират и подават от SQL, не бях сигурен кои декларации могат да бъдат от решаващо значение за отстраняване на неизправности тук, така че оставям кода до голяма степен непокътнат тук.

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
exec sql include sqlca;

// OK - Here we GO
void main()
{
    // First, create all the variables that we will need to communicate between 
    // the "C" program and the database
    exec sql begin declare section;
        //VARCHAR sLastName[51], sFirstName[51], sHotelName[51], sCheckInDate[12], sRoom[11];
        VARCHAR sLastName[51], sFirstName[51], sHotelName[51], sTransDate[11];
        //int nDays, nGuest_ID, nCount;
        int nGuest_ID, nQuantity, nUnitPrice, nCount, nHotelID, nItemID;
        //VARCHAR sInCity[11];
        VARCHAR sItemName[31], sTaxable[11];
        VARCHAR sUserID[21], sPassword[21];
    exec sql end declare section;
/////// begin needs work ///////
        // Now define the cursor we will use to get all of the charges that the guest incurred at all hotels
    exec sql declare dbGuest cursor for
        Select G.Guest_ID, G.Last_Name, G.First_Name, C.Item_ID, C.Item_Name, C.Quantity, C.Unit_Price, C.Trans_Date, H.Hotel_Name, H.Hotel_ID, SI.Taxable
        From Hotel H, Charge C, Stay S, Guest G, Sales_Item SI Where
        C.Stay_ID=S.Stay_ID And H.Hotel_ID=S.Hotel_ID And G.Guest_ID=S.Guest_ID
            And SI.Item_ID=C.Item_ID
        Group By S.Guest_ID;
//////// end needs work ///////
    // Set up the user-id and password to access my database
    // Because we are using the local database on this server
    // we don't need to use any database location or SID
    strcpy(sUserID.arr,"myusername"); 
    strcpy(sPassword.arr,"mypassword"); 
    sUserID.len=strlen(sUserID.arr);
    sPassword.len=strlen(sPassword.arr);
    exec sql connect :sUserID identified by :sPassword;

    // sqlca.sqlcode is a variable that is set based on the last command sent in to the database
    // a value anything other than zero for what we just did (connect to the database) indicates
    // a error.
    if(sqlca.sqlcode !=0)
       {
        //printf("Sorry, cannot connect to server, pgm aborted %s\n",sqlca.sqlcode); //correction 2/5/14
        printf("Sorry, cannot connect to server, pgm aborted %d\n",sqlca.sqlcode); //change to %d
        exit(1);
       }
    //we made it here, so we were able to open the database correctly
    exec sql SELECT COUNT(*) INTO :nCount FROM Guest;
    printf ("There are %d Guests.\n",nCount);
    for(;;){
        // Read in through stdio the Guest we want to query, then set it up do we can use it
        printf("Enter a Guest_ID(type exit to terminate)>>\n");
        scanf("%d",nGuest_ID);
        //Guest_ID.len= strlen(Guest_ID.arr);
        if(nGuest_ID==0)
        {
            printf("BYE\n");
            exit(0);
        }
        printf("%s %s %s %s %d\n","Charge Summary for:", sFirstName.arr, sLastName.arr, " Guest_ID:", nGuest_ID);
        //printf("I do not work yet (type exit to terminate)>>\n");
                // Open our cursor and begin reading records
        exec sql open dbGuest;
        for(;;)
        {
            //exec sql fetch dbGuest into :nGuest_ID, :sLastName, :sFirstName, :sHotelName, :sCheckInDate, :nDays, :sRoom;
            exec sql fetch dbGuest into :nGuest_ID, :sLastName, :sFirstName, :nItemID, :sItemName, :nQuantity, :nUnitPrice, :sTransDate, :sHotelName, :nHotelID;
            if(sqlca.sqlcode !=0)  // If anything went wrong or we read past eof, stop the loop
            {
                break;
            }
            // Do the crazy stuff to end the C-Strings
            sLastName.arr[sLastName.len] = 0;
            sFirstName.arr[sFirstName.len] = 0;
            sItemName.arr[sItemName.len] = 0;
            sTransDate.arr[sTransDate.len] = 0;
            sHotelName.arr[sHotelName.len] = 0;

            // Print out the information for this guest
            printf("%s %d %s %s \n", "Sales_Item: ", nItemID, " - ", sItemName.arr);
        }
        // close the cursor and end the program
        exec sql close dbGuest ;
    }
    exit(0);
}

Сигурен съм, че правя някаква проста грешка, но не намерих нищо полезно при търсенето. Изпълнявам това на сървър и не получавам обратно отстраняване на грешки (това е единственият основен бъг, който не успях да разреша до този момент), така че това, което имате, е това, което имам и аз. Обикновено програмите на C ще се изпълняват в дебъгери, но това е ProC и съм някак загубен с цялото нещо с отстраняването на грешки в Oracle ProC (тъй като работи на отдалечена база данни). При този вид грешка обикновено подозирам, че паметта не се разпределя правилно, но не виждам нищо подобно тук.

Прегледах тези, но не помогнаха:

Грешка при сегментиране (изхвърлено ядро) грешка по време на изпълнение в C

Не толкова полезна грешка -- Грешка в сегментирането (Core Dump) в домашното задание

Грешка при сегментиране (изхвърлено ядро)

Грешка на сегментиране (изхвърлено ядро) четене от stdin


person stackuser    schedule 19.02.2014    source източник
comment
dbx core <ur_object_name> може да ви покаже последния изпълнен ред!   -  person Maheswaran Ravisankar    schedule 20.02.2014
comment
dbx не е активиран на този сървър   -  person stackuser    schedule 20.02.2014


Отговори (1)


Тъй като nGuest_ID е int, когато извиквате scanf(), ще трябва да предоставите адрес на nGuest_ID:

scanf("%d",&nGuest_ID);

Това е вероятната причина за дъмпа на ядрото, който изпитвате, но също така OracleUser направи някои отлични предложения.

Надявам се това да помогне.

person Mark J. Bobak    schedule 19.02.2014
comment
Да, благодаря +1, което позволява на кода да продължи. Но се чудя защо работи така -- Charge Summary for: }▒ Guest_ID: 1 след като трябва да отпечата фамилното и собственото име. Възможно ли е това да е проблем с реда, в който инициализирам променливите, или просто се натъкнах на съвсем различен проблем? - person stackuser; 20.02.2014
comment
Изглежда, че sFirstName и sLastName са декларирани, но не са инициализирани или попълнени никъде, преди да се опитате да ги отпечатате. Така че просто отпечатвате произволни боклуци от паметта. - person Mark J. Bobak; 20.02.2014
comment
@MarkJ.Bobak страхотно +1 !! Пропуснах да прочета scanf!! Само на mm от успеха!! - person Maheswaran Ravisankar; 20.02.2014