Hi All,

Need our expertise out there regarding the above mention error and below are the codes:

/* send SQL query */

   bzero(query1, sizeof(query1));
   sprintf(query1, "select a.CreateDate, a.MobileNumber, b.BillName, b.CorrName, b.ICNew, b.ICOld, b.Passport,"
   "b.Addr, b.Addr2, b.Addr3, b.Addr4, b.Postcode, b.CountryCode from Register as a, Profile as b"
   " where a.MasterNumber = b.Number and a.Status=0");

   printf ("%s\n",query1);

   if (mysql_query(&conn, query1))
   {
        fprintf(stderr, "%s\n", mysql_error(&conn));
        exit(0);
   }


   res = mysql_use_result(&conn);


   /* output fields 0, 1 and 2 of each row */
   while ((row = mysql_fetch_row(res)) != NULL)
   {
      if (i==11)
      {
        timebuffer();
        i=1;
        bzero(string1, sizeof(string1));
      }
      else
      {
         sprintf(string1,"%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s", 
row[0], row[1], row[14], row[15], row[16], row[17], row[18], row[4], 
row[5], row[6], row[7], row[12], row[13]);
sprintf(mobileno,"%s", row[1]);
printf ("%s\n",string1);

        printf ("Test: %s\n",mobileno);
        writeLogFile(string1, mobileno);
        i++;
      }
    }

When I run the program, it gives me "Segmentation Fault" and I think it's mayb becos of combining 2 tables.

Many thanks..

Dani AI

Generated

Short expert addendum that pulls the useful bits from the thread and adds a few practical safeguards.

Good catch by about out‑of‑range indexing, and well spotted by that a bad format specifier in the filename sprintf can trigger undefined behavior — that alone can cause a crash even if the rest of the logic looks fine. Beyond those two, the usual causes for intermittent segmentation faults here are: uninitialized counters (example: i), NULL pointers returned for SQL NULL fields, buffer overruns when concatenating many columns, and failing to check return values (file I/O, mysql_* calls).

Quick checklist to harden the program:

  • Initialize loop/counter variables before use (e.g. set i = 1;).
  • Before indexing a row value, test it: treat row[col] == NULL as an empty string.
  • Limit writes with size-aware routines: prefer snprintf(buf, sizeof buf, ...) to sprintf.
  • Ensure you only access columns 0..(fieldcount-1) from the resultset; check the result field count once after the query.
  • Call mysql_free_result() and mysql_close() after the fetch loop, not inside it.
  • Check fopen() and fputs() return values and handle errors (avoid assuming file writes always succeed).
  • If many fields are concatenated into one buffer, either size the buffer conservatively or build the final string with repeated snprintf calls that advance the position and check remaining space.

Two easy improvements you can apply immediately:

  • Combine address parts on the SQL side so C never has to guess separators:

    SELECT ..., CONCAT_WS(', ', b.Addr, b.Addr2, b.Addr3) AS Address, ...

    CONCAT_WS skips NULLs and keeps separators correct.

  • Use SELECT DISTINCT or an appropriate GROUP BY to remove duplicate rows in SQL rather than deduplicating in C.

If the crash remains hard to reproduce, build with debugging symbols and run under gdb (gcc -g ..., gdb ./prog, run, bt) to get an exact backtrace — that will show precisely which line triggers the segfault.

Recommended Answers

All 10 Replies

you should post variable declaractions too.

sorry..aku post again my codes:

int main(int argc, char *argv[])
{

   char string1[1600], string2[1600], query[1600], query1[1600], mobileno[50];
   int i, j, len;
   FILE *fp2;


   mysql_init(&conn);

   /* Connect to database */
   if (!mysql_real_connect(&conn, host, user, password, database, 0, NULL, 0)) {
      fprintf(stderr, "%s\n", mysql_error(&conn));
      exit(0);
   }

/* send SQL query */

   bzero(query1, sizeof(query1));
   sprintf(query1, "select a.CreateDate, a.MobileNumber, b.BillName, b.CorrName, b.ICNew, b.ICOld, b.Passport,"
   "b.Addr, b.Addr2, b.Addr3, b.Addr4, b.Postcode, b.CountryCode from Register as a, Profile as b"
   " where a.MasterNumber = b.Number and a.Status=0");

   printf ("%s\n",query1);

   if (mysql_query(&conn, query1))
   {
        fprintf(stderr, "%s\n", mysql_error(&conn));
        exit(0);
   }


   res = mysql_use_result(&conn);


   /* output fields 0, 1 and 2 of each row */
   while ((row = mysql_fetch_row(res)) != NULL)
   {
      if (i==11)
      {
        timebuffer();
        i=1;
        bzero(string1, sizeof(string1));
      }
      else
      {
         sprintf(string1,"%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s", 
row[0], row[1], row[14], row[15], row[16], row[17], row[18], row[4], 
row[5], row[6], row[7], row[12], row[13]);
sprintf(mobileno,"%s", row[1]);
printf ("%s\n",string1);

        printf ("Test: %s\n",mobileno);
        writeLogFile(string1, mobileno);
        i++;
      }

/* Release memory used to store results and close connection */
   mysql_free_result(res);
   mysql_close(&conn);

   return 0;
}

    }

Your query has 13 columns in the resultset, but you are attempting to access 18 of them -- row[0] through row[17] is 18 columns, not 13. only row[0] through row[12] are valid.

ooohhhh..thanks..i thought..the declared row depends on the row inside the table of database..

how to combine the rows?. actually i want to combine addr and addr2 to become for example address but separated with (,).

ley say addr = no.17
addr2 = loke yew road
and it should be = no.17,loke yew road

when it was printed it should be:

2006-12-02 13:53:24|0134216014|ZAHARI BIN MOHAMED|ZAHARI BIN MOHAMED|580513-03-5667|5598577||LOT 1075,KAMPUNG JERANGAU|17500 TANAH MERAH||17500|MAL

instead of

2006-12-02 13:53:24|0134216014|ZAHARI BIN MOHAMED|ZAHARI BIN MOHAMED|580513-03-5667|5598577||LOT 1075|KAMPUNG JERANGAU|17500 TANAH MERAH||17500|MAL

if the above query being printed

thanks

you can easily put the comma wherever you want it in the sprintf() format string. Just replace one of those pipe symbols | with a comma.

ok..that's 1 idea...how about if there is 2 rows that have same value but i should display only 1..meaning that, i should check if 2 column have same value..i should display only 1..


Thanks for ur help...

you need to make your program a little more complex. Instead of one big spirntf() line you need to create a loop, for each row, search all rows from 0 to current row-1 to see if it is a duplicate, if not then use strcat() to copy its value into string1 array. Note that you will not use sprintf() at all.

hi guys..

sorry for asking again regarding segmentation fault..my query consists of 12 columns in the resultset and I already called to access from row[0] until row[11]...when I try to run the program...I still got the segmentation fault...

here is my latest code:

sprintf(query1, "select a.MobileNumber, b.BillName, b.ICNew, b.Passport,"
   "b.Addr, b.Addr2, b.Addr3, b.Addr4, b.Postcode, b.CountryCode, a.CreateDate, a.Source from Register as a, Profile as b"
   " where a.MasterNumber = b.Number and a.Status=0");

   //printf ("%s\n",query1);

   if (mysql_query(&conn, query1))
   {
        fprintf(stderr, "%s\n", mysql_error(&conn));
        exit(0);
   }


   res = mysql_use_result(&conn);


   /* output fields 0, 1 and 2 of each row */
   while ((row = mysql_fetch_row(res)) != NULL)
   {
      if (i==11)
      {
        timebuffer();
        i=1;
        bzero(string1, sizeof(string1));
      }
      else
      {
       escapeSpecialChar(row[2]);

       strcpy(var1,row[9]);
       if ( strcmp(var1,"MAL" ) == 0 )
       {
        strcpy (var1, "MALAYSIA");
          strcpy(var2, var1);
       }
        
       DB2date(row[10]);

         sprintf(string1,"%s|%s|%s|%s|%s,%s|%s,%s|%s|%s|%s|%s|", 
       row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], var2, newDate, row[11]);
         sprintf(mobileno,"%s", row[0]);
       printf ("%s\n",string1);

      //printf ("Test: %s\n",mobileno);
        writeLogFile(string1, mobileno);
        i++;
      }
    }
void writeLogFile(char line2[1600], char* MobileNo)
{
    char * mobile = "0192426699";
    //char * mobile = MobileNo;
      mobile = MobileNo;

    FILE *fp;
    FILE *fp2;
    char len[255];
    char filename[255];
     int min;
    int hour;
    int day;
    int mon;
        int yr;
        time_t tvec = time(0);
        struct tm* dtime;

        //time(&tvec);
        dtime = localtime(&tvec);

    min = dtime->tm_min  ;
    hour = dtime->tm_hour  ;
    day = dtime->tm_mday  ;
        mon = dtime->tm_mon + 1 ;
        yr = dtime->tm_year  +1900;

    sprintf(filename,"twop_%04s""%02d""%02d""%02d""%02d"".dat",yr,mon,day,hour,min);

       // Filename Format twop_yyyyMMddhhmm.dat 

 
            fp=fopen(filename, "a+");
        
                  if ( (fputs(line2, fp)) == EOF) 
          {
                      printf("error write...");
          }

                  if ( (fputs("\n", fp)) == EOF) 
          {
                      printf("error write1...");
                  }

        //printf ("Test2: %s\n",mobile);
        UpdateStatus(mobile, line2);
            bzero(line2, strlen(line2));
            strcpy (line2, "1");

            fclose(fp);      
}

and the result something like this:

0135712114|MALIK BIN JANG|68100311355821||171, JLN KAMPUNG SERPAN LAUT,KAMPUNG SERPAN LAUT,|94600 ASAJAYA,|94600|MALAYSIA|05-12-2006|1|
Segmentation fault

it seems like, it fails to write into a file caused the segmentation fault...is it true? n how to solve this...many thanks...

Hi guys..

I already solved the above problem...i just only change this portion:

sprintf(filename,"twop_%04d""%02d""%02d""%02d""%02d"".dat",yr,mon,day,hour,min);

Thanks

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.