Thread: curious runtime error!!

  1. #1
    Registered User zouyu1983's Avatar
    Join Date
    Nov 2006
    Location
    Fuzhou University, Fujian, China
    Posts
    35

    Smile curious runtime error!!

    a few days ago, i helped my girlfriend to write a c program. the program collapseed when i inputed the data and press enter.
    the source code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <process.h>
     
    
    #define STU_NAME_LEN 8
     
    typedef struct
    {
     char stuName[STU_NAME_LEN];
     float chinese;
     float math;
     float english;
    } StudentInfo;
     
    StudentInfo* stuArray = NULL;
    int stuNum = 0;
     
    int controlThread = 1;
    int function = 0;
    HANDLE Mutex;
    void bubleSort(int i)
    {
     int j;
     StudentInfo temp;
     float** select = malloc(sizeof(float*) * stuNum);
     if (select == NULL) exit(1);
     
     switch (i)
     {
     case 1: 
      {
       for (j=0; j<stuNum; j++) select[j] = &stuArray[j].chinese;
       break;
      } 
     case 2: 
      {
       for (j=0; j<stuNum; j++) select[j] = &stuArray[j].english;
       break;
      } 
     case 3: 
      {
       for (j=0; j<stuNum; j++) select[j] = &stuArray[j].math;
       break;
      }
     default: ;
     }
     for (i=stuNum; i>1; i--)
     {
      for (j=0; j<i - 1; j++)
      {
       if (*select[j] > *select[j + 1])
       {
        temp = stuArray[j];
        stuArray[j] = stuArray[j + 1];
        stuArray[j + 1] = temp;
       }
      }
     }
     
     free(select);
     return;
     
    }
     
    void sort()
    {
     int i;
     printf("please input the subject that you want to set to the keyword\n\
    1. chinese    2. english    3. math\n\
    select: ");
     scanf("%d", &i);
     bubleSort(i);
     return;
    }
     
    void print()
    {
     int i;
     printf("the detail information of the students : \n");
     for (i=0; i<stuNum; i++)
     {
      printf("%d. %s\n", i, stuArray[i].stuName);
      printf("english score : %g\n", stuArray[i].english);
      printf("chinese score : %g\n", stuArray[i].chinese);
      printf("math score : %g\n", stuArray[i].math);
      printf("\n");
     }
     return;
    }
     
    void search()
    {
     int i;
     char name[STU_NAME_LEN];
     int j = 0;
     printf("input the name you search : ");
     scanf("%s", name);
     for (i=0; i<stuNum; i++)
     {
      if (strcmp(name, stuArray[i].stuName) == 0)
      {
       printf(" %s\n", stuArray[i].stuName);
       printf("english score : %g\n", stuArray[i].english);
       printf("chinese score : %g\n", stuArray[i].chinese);
       printf("math score : %g\n", stuArray[i].math);
       printf("\n");
      }
      j = 1;
     }
     if (j == 0) printf("no student\n");
     return;
    }
     
    void inputData()
    {
     int i;
     for (i=0; i<stuNum; i++)
     {
      printf("input information of the %dth student:\n", i + 1);
      printf("student name: ");
      scanf("%s", stuArray[i].stuName);
      printf("chinese score: ");
      scanf("%f", &stuArray[i].chinese);   /*error*/
      printf("math score: ");
      scanf("%f", &stuArray[i].math);      /*error*/
      printf("english score: ");
      scanf("%f", &stuArray[i].english);    /*error*/
     }
     return;
    }
     
    void statistics()
    {
     int i;
     double totalEnglishScore = 0.0,
         totalChineseScore = 0.0,
         totalMathScore = 0.0;
    /* double max[3];  /*max[0] english , max[1] chinese , max[2] math
     double min[3];
     for (i=0; i<3; i++)
     {
      max[i] = 0.0;
      min[i] = 9999.9;
     }
    */
     for (i=0; i<stuNum; i++)
     {
      totalEnglishScore += stuArray[i].english;
      totalChineseScore += stuArray[i].chinese;
      totalMathScore += stuArray[i].math;
     }
     printf("the average score of english is : %g\n" , totalEnglishScore / stuNum);
     printf("the average score of chinese is : %g\n" , totalChineseScore / stuNum);
     printf("the average score of math is : %g\n" , totalMathScore / stuNum);
    }
     
    void welcome()
    {
     printf("\
     *****************************************************\n\
     **************  homework of OS **********************\n\
     **************  author: 柯舒勤 **********************\n\
     ************** date: 2006.11.20 *********************\n\n");
     return;
    }
     
    unsigned __stdcall InputData(void* pArguments)
    {
     while (controlThread)
     {
      if (function == 1)
      {
       WaitForSingleObject(Mutex, INFINITE);
       system("cls");
       welcome();
       inputData();
       function = 0;
       system("pause");
       ReleaseMutex(Mutex);
      }
      Sleep(200);
     }
     _endthreadex(0);
     return 0;
    }
     
    unsigned __stdcall Statistics(void* pArguments)
    {
     while (controlThread)
     {
      if (function == 4)
      {
       WaitForSingleObject(Mutex, INFINITE);
       system("cls");
       welcome();
       statistics();
       function = 0;
       system("pause");
       ReleaseMutex(Mutex);
      }
      Sleep(200);
     }
     _endthreadex(0);
     return 0;
    }
     
    unsigned __stdcall Search(void* pArguments)
    {
     while (controlThread)
     {
      if (function == 3)
      {
       WaitForSingleObject(Mutex, INFINITE);
       system("cls");
       welcome();
       search();
       function = 0;
       system("pause");
       ReleaseMutex(Mutex);
      }
      Sleep(200);
     }
     _endthreadex(0);
     return 0;
    }
     
    unsigned __stdcall Sort(void* pArguments)
    {
     while (controlThread)
     {
      if (function == 2)
      {
       WaitForSingleObject(Mutex, INFINITE);
       system("cls");
       welcome();
       sort();
       print();
       function = 0;
       system("pause");
       ReleaseMutex(Mutex);
      }
      Sleep(200);
     }
     _endthreadex(0);
     return 0;
    }
     
    int main()
    { 
     int i;
        HANDLE hThread[4];
        unsigned threadID[4];
     
     Mutex = CreateMutex(NULL,FALSE,NULL);
     printf("Please input the number of the students : ");
     scanf("%d", &stuNum);
     stuArray = (StudentInfo*)malloc(sizeof(StudentInfo) * stuNum);
     if (stuArray == NULL) 
     {
      printf("allocate failed!");
      exit(1);
     }
        hThread[0] = (HANDLE)_beginthreadex(NULL, 0, &InputData, NULL, 0, &threadID[0]);
        hThread[1] = (HANDLE)_beginthreadex(NULL, 0, &Search, NULL, 0, &threadID[1]);
        hThread[2] = (HANDLE)_beginthreadex(NULL, 0, &Sort, NULL, 0, &threadID[2]);
        hThread[3] = (HANDLE)_beginthreadex(NULL, 0, &Statistics, NULL, 0, &threadID[3]);
     
    
     while (function != 5)
     {
      WaitForSingleObject(Mutex, INFINITE);
      system("cls");
      welcome();
      printf("1. input data  2. sort  3. search  4. statistic  5. exit   ");
      scanf("%d", &function);
     
      system("pause");
      if (function < 1 && function > 5) printf("error\n");
      ReleaseMutex(Mutex);
     }
     
     controlThread = 0;
     for (i=0; i<4; i++) WaitForSingleObject(hThread[i], INFINITE);
     for (i=0; i<4; i++) CloseHandle(hThread[i]);
     CloseHandle(Mutex);
     
     free(stuArray);
     return 0;
    }
    the error was caused by scanf("%f",&stuArray[i].chinese)
    but i change the scanf("%f", .....) to scanf("%lf",.......), it run correctly. it is so curious that i can't understand,who can tell me why?my compile environment is vc.net(2003)

    ps: sorry, i come from china, so i can't express my purpose correctly in english
    Last edited by zouyu1983; 11-25-2006 at 12:50 PM.

  2. #2
    MFC killed my cat! manutd's Avatar
    Join Date
    Sep 2006
    Location
    Boston, Massachusetts
    Posts
    870
    Quote Originally Posted by zouyu1983
    i helped my girlfriend to write a c program
    How romantic Anyways, %lf indicates a double, rather than a float.
    Silence is better than unmeaning words.
    - Pythagoras
    My blog

  3. #3
    Registered User zouyu1983's Avatar
    Join Date
    Nov 2006
    Location
    Fuzhou University, Fujian, China
    Posts
    35
    but scanf("%f",....) will induce a runtime error
    and changing to scanf("%lf",......), it will be ok

  4. #4
    MFC killed my cat! manutd's Avatar
    Join Date
    Sep 2006
    Location
    Boston, Massachusetts
    Posts
    870
    Exactly, because you're scanning a double. Thus you use %lf.
    Silence is better than unmeaning words.
    - Pythagoras
    My blog

  5. #5
    Registered User zouyu1983's Avatar
    Join Date
    Nov 2006
    Location
    Fuzhou University, Fujian, China
    Posts
    35
    the compile environment is winXP sp2, vc.net(2003), and change one compiler option to /MD,which can induce a multiple threads runtime library

  6. #6
    Registered User zouyu1983's Avatar
    Join Date
    Nov 2006
    Location
    Fuzhou University, Fujian, China
    Posts
    35
    Quote Originally Posted by manutd
    Exactly, because you're scanning a double. Thus you use %lf.
    i'm scanning a float,
    this is the declaration for the sturct:
    Code:
    typedef struct
    {
     char stuName[STU_NAME_LEN];
     float chinese;
     float math;
     float english;
    } StudentInfo;

  7. #7
    MFC killed my cat! manutd's Avatar
    Join Date
    Sep 2006
    Location
    Boston, Massachusetts
    Posts
    870
    Hmm, I don't know
    Silence is better than unmeaning words.
    - Pythagoras
    My blog

  8. #8
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Code:
    &stuArray[i].english
    &stuArray[i].math
    &stuArray[i].chinese
    You say you did that at the bottom, but in the code it is not like that. It would not compile if it was not though, so I'm a little confused.

  9. #9
    Registered User zouyu1983's Avatar
    Join Date
    Nov 2006
    Location
    Fuzhou University, Fujian, China
    Posts
    35
    Quote Originally Posted by Tonto
    Code:
    &stuArray[i].english
    &stuArray[i].math
    &stuArray[i].chinese
    You say you did that at the bottom, but in the code it is not like that. It would not compile if it was not though, so I'm a little confused.
    sorry, i'm not good at english, so i don't understand what you said,
    what does "It would not compile if it was not though" mean?
    i don't know how to transfer "though" to my mother language in this sentence

  10. #10
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Well before your code said:

    Code:
      scanf("%s", stuArray[i].stuName);
      printf("chinese score: ");
      scanf("%f", &stuArray.chinese);   /*error*/
      printf("math score: ");
      scanf("%f", &stuArray.math);      /*error*/
      printf("english score: ");
      scanf("%f", &stuArray.english);    /*error*/
    Without the those array subscripts for the stuArray. You have now edited your post so that it says

    Code:
      scanf("%s", stuArray[i].stuName);
      printf("chinese score: ");
      scanf("%f", &stuArray[i].chinese);   /*error*/
      printf("math score: ");
      scanf("%f", &stuArray[i].math);      /*error*/
      printf("english score: ");
      scanf("%f", &stuArray[i].english);    /*error*/
    Do you still recieve errors then?

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    If the variables are defined as float, then "%f" is the correct scanf usage.

    However, that's not your only problem

    new.c:32: warning: assignment from incompatible pointer type
    new.c:37: warning: assignment from incompatible pointer type
    new.c:42: warning: assignment from incompatible pointer type
    For all these lines
    for (j=0; j<stuNum; j++) select[j] = &stuArray[j].chinese;
    They exist in the struct as floats, yet you compare and swap them as doubles.

    This is going to corrupt the memory very severely.

    > printf("please input the subject that you want to set to the keyword\n\
    > 1. chinese 2. english 3. math\n\
    > select: ");
    The correct way to wrap long strings is like this
    Code:
     printf("please input the subject that you want to set to the keyword\n"
            "1. chinese    2. english    3. math\n"
            "select: ");
    Not all compilers will wrap long strings joined together with a \
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User zouyu1983's Avatar
    Join Date
    Nov 2006
    Location
    Fuzhou University, Fujian, China
    Posts
    35
    Quote Originally Posted by Tonto
    Well before your code said:

    Code:
      scanf("%s", stuArray[i].stuName);
      printf("chinese score: ");
      scanf("%f", &stuArray.chinese);   /*error*/
      printf("math score: ");
      scanf("%f", &stuArray.math);      /*error*/
      printf("english score: ");
      scanf("%f", &stuArray.english);    /*error*/
    Without the those array subscripts for the stuArray. You have now edited your post so that it says

    Code:
      scanf("%s", stuArray[i].stuName);
      printf("chinese score: ");
      scanf("%f", &stuArray[i].chinese);   /*error*/
      printf("math score: ");
      scanf("%f", &stuArray[i].math);      /*error*/
      printf("english score: ");
      scanf("%f", &stuArray[i].english);    /*error*/
    Do you still recieve errors then?
    oh,sorry, i deleted the [i] uncarefully when i post the code
    my source code is scanf("%f", &stuArray[i].chinese) .........
    and it take runtime error

    but change them to scanf("%lf",....) , the program runs correctly

  13. #13
    Registered User zouyu1983's Avatar
    Join Date
    Nov 2006
    Location
    Fuzhou University, Fujian, China
    Posts
    35
    Quote Originally Posted by Salem
    If the variables are defined as float, then "%f" is the correct scanf usage.

    However, that's not your only problem

    new.c:32: warning: assignment from incompatible pointer type
    new.c:37: warning: assignment from incompatible pointer type
    new.c:42: warning: assignment from incompatible pointer type
    For all these lines
    for (j=0; j<stuNum; j++) select[j] = &stuArray[j].chinese;
    They exist in the struct as floats, yet you compare and swap them as doubles.

    This is going to corrupt the memory very severely.

    > printf("please input the subject that you want to set to the keyword\n\
    > 1. chinese 2. english 3. math\n\
    > select: ");
    The correct way to wrap long strings is like this
    Code:
     printf("please input the subject that you want to set to the keyword\n"
            "1. chinese    2. english    3. math\n"
            "select: ");
    Not all compilers will wrap long strings joined together with a \
    oh, that's my mistakes, when i found scanf("%lf",.....) will eliminate the error, i change the float to double, and send the code to my GF, but before i post the code , i change the double to the float and forget to change double** select to float** select
    thank you for pointing the mistake

    but the key problem is when i use scanf("%f",....) as the input method for float chinese...
    the program will abort,but change it to scanf("%lf",....), the program will run well

  14. #14
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Not all compilers will wrap long strings joined together with a \
    Why not? The preprocessor handles that, and there's no reason it should replace \ at the end of lines elsewhere but not inside strings.

    It's definitely true that not all compilers support newlines inside strings, though:
    Code:
    printf("Hello,
    there");
    Since this works
    Code:
    #define abs(x) \
        ((x) > 0 ? (x) : -(x))
    I see no reason why this shouldn't
    Code:
    printf("Hello \
    there");
    Of course, I always do this anyway
    Code:
    printf("hello "
        "there");
    so that I can indent the succeeding lines.

    Am I missing something?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  15. #15
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    I see no reason why this shouldn't
    Maybe because he first one is inside preprocessor's directive and the second one - not. Why preprocessor should bother to do something with the second slash?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Testing some code, lots of errors...
    By Sparrowhawk in forum C Programming
    Replies: 48
    Last Post: 12-15-2008, 04:09 AM
  2. Connecting to a mysql server and querying problem
    By Diod in forum C++ Programming
    Replies: 8
    Last Post: 02-13-2006, 10:33 AM
  3. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. Stupid compiler errors
    By ChrisEacrett in forum C++ Programming
    Replies: 9
    Last Post: 11-30-2003, 05:44 PM