I am trying to write a basic mutant testing script in C, but I've come across some errors which I cannot seem to solve. The first thing to comment is that in the function that seems to be having problems, namr, I try am trying to name the file I am creating using a simple caesar cypher to avoid having unwanted characters in the file name. When I run it as is, it seems as though the strings cexp and mcexp are sometimes getting content from a file I am reading in another function switchr.
When I add the printf at Annotation 1 it seems to run fine but the filenames come out wrong. Still, if I comment Annotation 1 out, there is a malloc(): corrupted top size error. I have tried various prints to see what is wrong. By the time it gets to Annotation 2, cexp and mcexp are still the desired length and content but, by the time they get to Annotation 3, they're 26 or 25 characters long and include the starting lines of the file I am reading in other parts of the script.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *namr(char *exp, char *mexp, int ignv) {
int explen = strlen(exp);
int mexplen = strlen(mexp);
//printf("EXPLEN: %d MEXPLEN: %d\n",explen,mexplen);
//ANNOTATION 1
char *cexp = (char *)malloc(explen + 1);
char *cmexp = (char *)malloc(mexplen + 1); //Exp in Caeser Cipher
for (int i = 0; i < explen; i++) {
cexp[i]= (exp[i] ? 'A' + exp[i] % 25 : exp[i]);
printf("%d - %c - %c\n", i, exp[i], 'A' + exp[i] % 25);
//ANNOTATION 2
}
for (int i = 0; i < mexplen; i++) {
cmexp[i]= (mexp[i] ? 'A' + mexp[i] % 25 : mexp[i]);
}
printf("EXP: %s\nMEXP: %s\n", exp, mexp);
printf("CEXP: %s\nCMEXP: %s\n", cexp, cmexp);
//ANNOTATION 3
printf("%s - %d\n%s - %d\n%d\n", cexp, strlen(cexp),
cmexp, strlen(cmexp), strlen("./U_SWITCH_MTNTS/TO%03.c"));
char *outname = (char *)malloc((30 + explen + mexplen));
sprintf(outname, "./U_SWITCH_MTNTS/%sTO%s%03d.c", cexp, cmexp, ignv);
free(cexp);
free(cmexp);
return outname;
}
int countr(char *filename, char *exp) {
int out = 0;
int i, flag;
int inlen = strlen(exp);
char c;
FILE *f = fopen(filename, "r");
while (c != EOF) {
for (i = 0, flag = 0; i < inlen; i++) {
if (exp[i] != c) {
flag = 1;
break;
}
c = getc(f);
}
if (flag == 0)
out++;
c = getc(f);
}
fclose(f);
return out;
}
char *switchr(char *filename, char *exp, char *mexp, int ignv) {
int i, flag,buffcount;
FILE *f = fopen(filename, "r");
char *outname = namr(exp, mexp, ignv);
FILE *fout = fopen(outname, "w");
char c = getc(f);
int ignc = ignv;
int inlen = strlen(exp);
char *buffer = (char *)malloc(inlen * sizeof(char));
while (c != EOF) {
for (i = 0, flag = 0, buffcount = 0; i < inlen; i++) {
if (exp[i] != c) {
flag = 1;
break;
} else {
buffer[buffcount] = c;
buffcount++;
c = getc(f);
}
}
if (flag == 0) {
if(ignc == 0) {
fputs(mexp, fout);
} else {
for (i = 0; i < buffcount; i++)
fputc(buffer[i], fout);
}
ignc--;
} else {
for (i = 0; i < buffcount; i++)
fputc(buffer[i], fout);
}
fputc(c, fout);
c = getc(f);
}
fclose(f);
fclose(fout);
return outname;
}
void mstrswitch(char *filename) {
int ecount = countr(filename, "==");
char **filenames = (char **)malloc(5 * ecount * sizeof(char *));
char command[100];
system("mkdir U_SWITCH_MTNTS");
system("mkdir TEST_OBJECTS");
for (int i = 0;i < ecount; i++) {
filenames[5 * i] = switchr("test.c", "==", "<=", i);
filenames[5 * i + 1] = switchr("test.c", "==", ">=", i);
filenames[5 * i + 2] = switchr("test.c", "==", ">", i);
filenames[5 * i + 3] = switchr("test.c", "==", "<", i);
filenames[5 * i + 4] = switchr("test.c", "==", "!=", i);
}
for (int i = 0; i < 5 * ecount; i++) {
sprintf(command, "gcc -o ./TEST_OBJECTS/test%03d %s", i, filenames[i]);
system(command);
sprintf(command, "./TEST_OBJECTS/test%03d", i);
system(command);
free(filenames[i]);
}
free(filenames);
}
int main() {
mstrswitch("test.c");
return 0;
}
You never zero terminates the strings cexp and cmexp. So add these two lines:
for(int i=0;i<explen;i++)
{
cexp[i]= (exp[i]?'A'+exp[i]%25: exp[i]);
printf("%d - %c - %c\n",i,exp[i],'A'+exp[i]%25);
}
cexp[explen]= '\0'; <------------------- add
for(int i=0;i<mexplen;i++)
{
cmexp[i]= (mexp[i]?'A'+mexp[i]%25: mexp[i]);
}
cmexp[mexplen]= '\0'; <------------------- add
Besides that the following line looks strange:
cexp[i]= (exp[i]?'A'+exp[i]%25: exp[i]);
^^^^^^
Always true
Having a condition that always returns true is probably not what you intended.
Related
I am using YOLO for object detection and wanted to edit the code files to run detection on all the images in a folder and I found this function Github link to the function
I edited the "test_detector" function as follows from here:
while (1) {
folder = opendir("./result_img/");
char str1[100] = "./result_img/";
while( (entry=readdir(folder)) != NULL)
{
if((strcmp(entry->d_name,".")==0 || strcmp(entry->d_name,"..")==0 || (entry->d_name) == '.' ) || (strcmp(entry->d_name,"Server_v1.py")==0))
{
printf(".");
sleep(0.5);
continue;
}
if (filename) {
strcat(str1, entry->d_name);
strncpy(input, str1, 256);
closedir(folder);
if (strlen(input) > 0)
if (input[strlen(input) - 1] == 0x0d) input[strlen(input) - 1] = 0;
}
else {
printf("Enter Image Path: ");
fflush(stdout);
input = fgets(input, 256, stdin);
if (!input) break;
strtok(input, "\n");
}
//image im;
//image sized = load_image_resize(input, net.w, net.h, net.c, &im);
image im = load_image(input, 0, 0, net.c);
image sized;
if(letter_box) sized = letterbox_image(im, net.w, net.h);
else sized = resize_image(im, net.w, net.h);
layer l = net.layers[net.n - 1];
int k;
for (k = 0; k < net.n; ++k) {
layer lk = net.layers[k];
if (lk.type == YOLO || lk.type == GAUSSIAN_YOLO || lk.type == REGION) {
l = lk;
printf(" Detection layer: %d - type = %d \n", k, l.type);
}
}
//box *boxes = calloc(l.w*l.h*l.n, sizeof(box));
//float **probs = calloc(l.w*l.h*l.n, sizeof(float*));
//for(j = 0; j < l.w*l.h*l.n; ++j) probs[j] = (float*)xcalloc(l.classes, sizeof(float));
float *X = sized.data;
//time= what_time_is_it_now();
double time = get_time_point();
network_predict(net, X);
//network_predict_image(&net, im); letterbox = 1;
printf("%s: Predicted in %lf milli-seconds.\n", input, ((double)get_time_point() - time) / 1000);
//printf("%s: Predicted in %f seconds.\n", input, (what_time_is_it_now()-time));
int nboxes = 0;
detection *dets = get_network_boxes(&net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes, letter_box);
if (nms) {
if (l.nms_kind == DEFAULT_NMS) do_nms_sort(dets, nboxes, l.classes, nms);
else diounms_sort(dets, nboxes, l.classes, nms, l.nms_kind, l.beta_nms);
}
draw_detections_v3(im, dets, nboxes, thresh, names, alphabet, l.classes, ext_output, input);
save_image(im, "predictions");
if (!dont_show) {
show_image(im, "predictions");
}
if (json_file) {
if (json_buf) {
char *tmp = ", \n";
fwrite(tmp, sizeof(char), strlen(tmp), json_file);
}
++json_image_id;
json_buf = detection_to_json(dets, nboxes, l.classes, names, json_image_id, input);
fwrite(json_buf, sizeof(char), strlen(json_buf), json_file);
free(json_buf);
}
// pseudo labeling concept - fast.ai
if (save_labels)
{
char labelpath[4096];
replace_image_to_label(input, labelpath);
FILE* fw = fopen(labelpath, "wb");
int i;
for (i = 0; i < nboxes; ++i) {
char buff[1024];
int class_id = -1;
float prob = 0;
for (j = 0; j < l.classes; ++j) {
if (dets[i].prob[j] > thresh && dets[i].prob[j] > prob) {
prob = dets[i].prob[j];
class_id = j;
}
}
if (class_id >= 0) {
sprintf(buff, "%d %2.4f %2.4f %2.4f %2.4f\n", class_id, dets[i].bbox.x, dets[i].bbox.y, dets[i].bbox.w, dets[i].bbox.h);
fwrite(buff, sizeof(char), strlen(buff), fw);
}
}
fclose(fw);
}
free_detections(dets, nboxes);
free_image(im);
free_image(sized);
if (dont_show) {
wait_until_press_key_cv();
destroy_all_windows_cv();
}
if (filename) break;
}
sleep(1);
printf("outside the loop");
char newname[100];
removeSubstrr(str1, "./result_img/");
sprintf(newname, "./pfiles/%s",str1);
//remove(input);
printf("newname %s\n",newname);
rename (input, newname);
//sleep(1);
}
if (json_file) {
char *tmp = "\n]";
fwrite(tmp, sizeof(char), strlen(tmp), json_file);
fclose(json_file);
}
// free memory
free_ptrs((void**)names, net.layers[net.n - 1].classes);
free_list_contents_kvp(options);
free_list(options);
int i;
const int nsize = 8;
for (j = 0; j < nsize; ++j) {
for (i = 32; i < 127; ++i) {
free_image(alphabet[j][i]);
}
free(alphabet[j]);
}
free(alphabet);
free_network(net);
}
When I am running the following code, it runs fine if the folder is not empty. once the folder is empty after sometime I get segmentation fault (core dumped) error. if i put "sleep(1)" at the end of first loop the code runs fine but every detection takes 1 second which is slow for the application.
I found that if i remove the line "if(filename)break;" the code stops at the end of the loop even when the folder is not empty.
filename is always true as it is passed through command line
Sort command of linux must sort the lines of a text file and transfer the output to another file. But my code gives a runtime error. Please rectify the pointer mistakes so that output.
In which line exactly should I make changes? Because there is no output after all.
I'm pasting the whole code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void sortfile(char **arr, int linecount) {
int i, j;
char t[500];
for (i = 1; i < linecount; i++) {
for (j = 1; j < linecount; j++) {
if (strcmp(arr[j - 1], arr[j]) > 0) {
strcpy(t, arr[j - 1]);
strcpy(arr[j - 1], arr[j]);
strcpy(arr[j], t);
}
}
}
}
int main() {
FILE *fileIN, *fileOUT;
fileIN = fopen("test1.txt", "r");
unsigned long int linecount = 0;
int c;
if (fileIN == NULL) {
fclose(fileIN);
return 0;
}
while ((c = fgetc(fileIN)) != EOF) {
if (c == '\n')
linecount++;
}
printf("line count=%d", linecount);
char *arr[linecount];
char singleline[500];
int i = 0;
while (fgets(singleline, 500, fileIN) != NULL) {
arr[i] = (char*)malloc(500);
strcpy(arr[i], singleline);
i++;
}
sortfile(arr, linecount);
for (i = 0; i < linecount; i++) {
printf("%s\n", arr[i]);
}
fileOUT = fopen("out.txt", "w");
if (!fileOUT) {
exit(-1);
}
for (i = 0; i < linecount; i++) {
fprintf(fileOUT, "%s", arr[i]);
}
fclose(fileIN);
fclose(fileOUT);
}
The problem in your code is you do not rewind the input stream after reading it the first time to count the number of newlines. You should add rewind(fileIN); before the next loop.
Note however that there are other problems in this code:
the number of newline characters may be less than the number of successful calls to fgets(): lines longer than 499 bytes will be silently broken in multiple chunks, causing more items to be read by fgets() than newlines. Also the last line might not end with a newline. Just count the number of successful calls to fgets().
You allocate 500 bytes for each line, which is potentially very wasteful. Use strdup() to allocate only the necessary size.
Swapping the lines in the sort routine should be done by swapping the pointers, not copying the contents.
allocating arr with malloc is safer and more portable than defining it as a variable sized array with char *arr[linecount];
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void sortfile(char **arr, int linecount) {
for (;;) {
int swapped = 0;
for (int j = 1; j < linecount; j++) {
if (strcmp(arr[j - 1], arr[j]) > 0) {
char *t = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = t;
swapped = 1;
}
}
if (swapped == 0)
break;
}
}
int main() {
FILE *fileIN, *fileOUT;
char singleline[500];
int i, linecount;
fileIN = fopen("test1.txt", "r");
if (fileIN == NULL) {
fprintf(stderr, "cannot open %s\n", "test1.txt");
return 1;
}
linecount = 0;
while (fgets(singleline, 500, fileIN)) {
linecount++;
}
printf("line count=%d\n", linecount);
char **arr = malloc(sizeof(*arr) * linecount);
if (arr == NULL) {
fprintf(stderr, "memory allocation failure\n");
return 1;
}
rewind(fileIN);
for (i = 0; i < linecount && fgets(singleline, 500, fileIN) != NULL; i++) {
arr[i] = strdup(singleline);
if (arr[i] == NULL) {
fprintf(stderr, "memory allocation failure\n");
return 1;
}
}
fclose(fileIN);
if (i != linecount) {
fprintf(stderr, "line count mismatch: i=%d, lilnecount=%d\n",
i, linecount);
linecount = i;
}
sortfile(arr, linecount);
for (i = 0; i < linecount; i++) {
printf("%s", arr[i]);
}
fileOUT = fopen("out.txt", "w");
if (!fileOUT) {
fprintf(stderr, "cannot open %s\n", "out.txt");
return 1;
}
for (i = 0; i < linecount; i++) {
fprintf(fileOUT, "%s", arr[i]);
}
fclose(fileOUT);
for (i = 0; i < linecount; i++) {
free(arr[i]);
}
free(arr);
return 0;
}
To get a different sort order, you would change the comparison function. Instead of strcmp() you could use this:
#include <ctype.h>
int my_strcmp(const char *s1, const char *s2) {
/* compare strings lexicographically but swap lower and uppercase letters */
unsigned char c, d;
while ((c = *s1++) == (d = *s2++)) {
if (c == '\0')
return 0; /* string are equal */
}
/* transpose case of c */
if (islower(c)) {
c = toupper(c);
} else {
c = tolower(c);
}
/* transpose case of d */
if (islower(d)) {
d = toupper(d);
} else {
d = tolower(d);
}
/* on ASCII systems, we should still have c != d */
/* return comparison result */
if (c <= d)
return -1;
} else {
return 1;
}
}
So this program crashes and tells me "Aborted (core dumped)" but only when my decleration of "GENERATIONS" is greater than 6... I know its a pain that I've uploaded the whole code but I really cant figure out where it is other than it's after the return from "fibonacci_quasicrystal_generator(GENERATIONS, crystal);", as the printf statement just after gets printed, then the message appears. Code below:
#define GENERATIONS 5
#define OUTFILE "frequencies.txt"
#define GNUPLOT_EXE "gnuplot"
#define GNUPLOT_SCRIPT "frequencyplot.script"
static void fibonacci_quasicrystal_generator(int generations, char * chain);
static int plot();
int main()
{
double k = 1.0, m_a = 100.0, m_b = 1.0, m = 0.0;
char * crystal = malloc(2);
//strcopy(crystal, "A"); //gsl_vector * y_vector = gsl_vector_calloc(CHAIN_LENGTH);
fibonacci_quasicrystal_generator(GENERATIONS, crystal);
if (crystal == NULL){
printf("Crystal write failed.");
exit(0);
}
int chain_length = strlen(crystal);
printf("%i member Crystal generated, after %i generations.\n", chain_length, GENERATIONS);
gsl_matrix * a_matrix = gsl_matrix_calloc(chain_length, chain_length);
gsl_matrix * b_matrix = gsl_matrix_calloc(chain_length, chain_length);
gsl_matrix_set_identity(b_matrix);
gsl_vector * eigenvalues_vector = gsl_vector_calloc(chain_length);
for (int i = 0; i < chain_length; ++i){
if (crystal[i] == 'A'){
m = m_a;
} else {
m = m_b;
}
for (int j = 0; j < chain_length; ++j){
if ((i == j) && (i != 0 && i != chain_length)){
gsl_matrix_set(a_matrix, i, j,(2*k)/m);
}
else if (i == j-1){
gsl_matrix_set(a_matrix, i, j,(-1)*(k/m));
}
else if (i == j+1){
gsl_matrix_set(a_matrix, i ,j, (-1)*(k/m));
}
}
}
gsl_eigen_gensymm_workspace * workspace = gsl_eigen_gensymm_alloc(chain_length);
gsl_eigen_gensymm(a_matrix, b_matrix, eigenvalues_vector, workspace);
gsl_eigen_gensymm_free(workspace);
free(crystal);
gsl_matrix_free(a_matrix);
gsl_matrix_free(b_matrix);
gsl_sort_vector(eigenvalues_vector);
FILE * outfile = fopen(OUTFILE, "w");
for (int i = 0; i < chain_length; ++i){
fprintf(outfile, "%e \t%i \r\n", pow(gsl_vector_get(eigenvalues_vector, i),2), i);
}
fclose(outfile);
gsl_vector_free(eigenvalues_vector);
plot();
return 0;
}
static void fibonacci_quasicrystal_generator(int generations, char * chain){
printf("generating fibonacci quasicrystal...\n");
int i;
i = 0;
char * chain_1 = malloc(2), * chain_2 = malloc(2), * tmp = malloc(2);
strcpy(chain_1, "B");
strcpy(chain_2, "A");
size_t chain_1_size = strlen(chain_1) + 1, chain_2_size = strlen(chain_2) + 1;
if (generations == 1){
chain = realloc(chain, chain_1_size);
snprintf(chain, chain_1_size, "%s", chain_1);
}
else if (generations == 2){
chain = realloc(chain, chain_2_size);
snprintf(chain, chain_2_size, "%s", chain_2);
}
else if (generations > 2){
size_t chain_3_size = strlen(chain_1) + strlen(chain_2) + 1;
char * chain_3 = malloc(chain_3_size);
printf("%i\n", generations);
for (i = 0; i < generations - 1; ++i){
printf("%i\n", i);
snprintf(chain_3, chain_3_size, "%s%s", chain_1, chain_2);
chain_1_size = chain_2_size;
chain_2_size = chain_3_size;
if ((tmp = realloc(chain_1, chain_1_size)) != NULL){
chain_1 = tmp;
}
if ((tmp = realloc(chain_2, chain_2_size)) != NULL){
chain_2 = tmp;
}
snprintf(chain_1, chain_1_size, "%s", chain_2);
snprintf(chain_2, chain_2_size, "%s", chain_3);
if (i < generations - 2){
chain_3_size = strlen(chain_1) + strlen(chain_2) + 1;
if ((tmp = realloc(chain_3, chain_3_size)) != NULL){
chain_3 = tmp;
} else {
printf("oops!\n");
exit(1);
}
}
}
chain = realloc(chain, chain_3_size);
snprintf(chain, chain_3_size, "%s", chain_3);
free(chain_3);
}
free(chain_1);
free(chain_2);
}
static int plot(){
char command[PATH_MAX];
snprintf(command, sizeof(command), "%s %s", GNUPLOT_EXE, GNUPLOT_SCRIPT);
system(command);
return 0;
}
The problem is that char *chain into fibonacci_quasicrystal_generator function has local scope: the function does not modify the crystal pointer of main, so that pointer is left with 2 bytes.
You can change the function to
static char *fibonacci_quasicrystal_generator(int generations, char * chain)
{
// YOUR STUFF
return chain;
}
And call it from main using
crystal = fibonacci_quasicrystal_generator(GENERATIONS, crystal);
You can achieve the same using a double pointer so
static void ibonacci_quasicrystal_generator(int generations, char ** chain)
My code has a memory leak problem. I don't know where I went wrong. Below is the code: I am trying to read from csv file and store a particular columns.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
FILE *result = fopen ("C:\\Users\\pa1rs\\Desktop\\local.csv", "w");
const char *text = "LOA,NAME,";
fprintf (result, "%s", text);
char *token;
char *endToken;
int lines = 0;
char ch; /* should check the result */
FILE *file = fopen ("C:\\Users\\pa1rs\\Desktop\\samplee.csv", "r");
char line[300];
if (file == NULL) {
perror ("Error opening the file");
} else {
while (!feof (file)) {
ch = fgetc (file);
if (ch == '\n') {
lines = lines + 1;
}
}
//printf(" no of lines existing in the file %d\n\n", lines);
}
fseek (file, 0, SEEK_SET);
while ((ch = fgetc (file)) != '\n') {
// we don't need the first line on sample.csv
// as it is just the description part
}
int s[lines - 1];
int j = 0;
char *N[lines - 1];
while (fgets (line, sizeof (line), file)) {
int i = 0;
token = line;
do {
endToken = strchr (token, ',');
if (endToken)
*endToken = '\0';
if (i == 3) {
s[j] = atoi (token);
}
if (i == 12) {
N[j] = (char *) malloc (strlen (token) * sizeof (char));
strcpy (N[j], token);
}
if (endToken)
token = endToken + 1;
i++;
} while (endToken);
j = j + 1;
}
//******************************************************unigue loa
int count = 0;
int g = 0;
int h = 0;
int LOA[lines - 1];
int dd = 0;
for (dd = 0; dd < lines - 1; dd++) {
LOA[dd] = 0;
}
for (g = 0; g < lines - 1; g++) {
for (h = 0; h < count; h++) {
if (s[g] == LOA[h])
break;
}
if (h == count) {
LOA[count] = s[g];
count++;
}
}
int xw = 0;
for (xw = 0; xw < count; xw++) {
//printf("%d \t",LOA[xw]);
}
//printf("LOA Array Length is: %d \n",count);
//********************************************************
////FOR UNIQUE NAMES ARRAY
//printf("No of unique names are %d",county);
//FOR UNIQUE CAUSES ARRAY
char *sa[9] =
{ "Monticello", "Valparaiso", "Crown Point", "Plymouth", "Goshen",
"Gary", "Hammond", "Laporte", "Angola" };
int countz = 0;
int gz = 0;
int hz = 0;
char *LOAz[lines - 1];
int zero2 = 0;
for (zero2 = 0; zero2 < lines - 1; zero2++) {
LOAz[zero2] = NULL;
}
for (gz = 0; gz < lines - 1; gz++) {
for (hz = 0; hz < countz; hz++) {
if (strcmp (N[gz], LOAz[hz]) == 0)
break;
}
if (hz == countz) {
LOAz[countz] = (char *) malloc (strlen (N[gz]) * sizeof (char));
strcpy (LOAz[countz], N[gz]);
countz++;
}
}
int nz = 0;
for (nz = 0; nz < countz; nz++) {
fprintf (result, "%s,", LOAz[nz]);
}
fprintf (result, "\n");
// printf("%d",countz);
//*****************************
int i = 0;
int jjj = 0;
int xxx = 0;
int ggg = 0;
int k = 0;
int kount[count][countz];
for (xxx = 0; xxx < count; xxx++) {
for (ggg = 0; ggg < countz; ggg++) {
kount[xxx][ggg] = 0;
}
}
for (i = 0; i < count; i++) {
for (k = 0; k < countz; k++) {
for (jjj = 0; jjj < lines - 1; jjj++) {
if (LOA[i] == s[jjj]) {
if (strcmp (LOAz[k], N[jjj]) == 0) {
kount[i][k]++;
}
}
}
}
}
int ig = 0;
int ik = 0;
for (ig = 0; ig < count; ig++) {
fprintf (result, "%d,%s", LOA[ig], sa[ig]);
for (ik = 0; ik < countz; ik++) {
fprintf (result, ",%d", kount[ig][ik]);
}
fprintf (result, "\n");
}
int rrr = 0;
free (N);
for (rrr = 0; rrr < lines - 1; rrr++) {
free (LOAz[rrr]);
}
//*****************************
//fclose(result);
fclose (file);
return 0;
}
Lines I got here is 13761 and LOAz was declared with array size lines-1=13761, but unique ones I got here are only 49, So I am reallocating memory for that and remaining are unused , I think problem started there.
Please help! Thanks in Advance.
One problem in your code is that you don't allocate enough memory for strings. For example, in these lines:
N[j] = (char*) malloc(strlen(token) * sizeof(char));
strcpy(N[j], token);
// ...
LOAz[countz] = (char*) malloc(strlen(N[gz]) * sizeof(char));
strcpy(LOAz[countz], N[gz]);
The problem is that strlen returns the number of non-zero symbols in the string. However, to store the string you need one more byte, to also store the zero terminating character, so the buffer size to store s should be at least strlen(s) + 1.
Also, a better coding style is to avoid casting the return value of malloc.
I have a problem with an "add calculator".
Valgrind reports no memory errors, no errors from compiler but the program doesn't show any output despite the printf - "Base is ".
All pointers, and variables are (n my opinion) correctly initialized.
getnum function gets a number, returns a pointer to char - char *,
add function processes two numbers as strings, returns result which is a pointer to char (char *) as well.
I don't know whether the problem is memory allocation or procedures connected to processing arrays...
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MAX(A,B) ((A)>(B) ? (A) : (B))
char *getnum(FILE *infile, int base)
{
int len = 10;
int c;
int pos = 0;
char *num = NULL;
char *tmpnum = NULL;
num = malloc(sizeof(char)*len);
while (((c = fgetc(infile)) != EOF) && (isalnum(c))) {
if (isdigit(c)) {
/* irrelevant*/
}
else if (isalpha(c)) {
fprintf(stderr, "Wrong base, expected 16\n");
free(num);
return NULL;
}
if (pos >= len) {
/*realloc*/
}
}
return num;
}
int main(int argc, char **argv)
{
FILE *infile = NULL;
char *number1 = NULL;
char *number2 = NULL;
char *result = NULL;
int base, i, j = 0, length, count = 0;
infile = fopen(argv[1], "r");
base = atoi(argv[2]);
while (!feof(infile)) {
number1 = getnum(infile, base);
number2 = getnum(infile, base);
break;
}
printf("Base is %d\n", base);
result = add(number1, number2, base);
length = strlen(result);
for (i = 0; i <= length - 1; i++) {
if (result[i] == '0') {
count++;
}
}
for (j = i; j == (length - 1); j++) {
printf("Result is: %s\n", &result[j]);
break;
}
free(result);
result = NULL;
fclose(infile);
return 0;
}
Trying to work it out for the past 4 hours and can't find a mistake.
Thanks in advance!
There is one severe typo near the end of main().
for (j = i; j == (length - 1); j++) {
/* ^^ SHOULD BE <= */
printf("Result is: %s\n", &result[j]);
break;
}
Looking at this code:
for (i = 0; i <= length - 1; i++) {
if (result[i] == '0') {
count++;
}
}
if (count == length) {
printf("Result is 0\n");
free(result);
result = NULL; /* arguable */
fclose(infile);
return 0;
}
for (i = 0; i <= length - 1; i++) {
if (result[i] != '0') {
break;
}
}
for (j = i; j == (length - 1); j++) {
printf("Result is: %s\n", &result[j]);
break;
}
Instead of counting the total number of zeroes in the output number, and then counting the number of leading zeroes again, why not combine the two?
What is the last loop about? It's not even really a loop - it will execute once if i is length - 1, or not at all if not (presumably you're hitting the latter case in your test input).
e.g.
for (count = 0; count < length; count++) {
if (result[count] != '0')
break;
}
if (count == length) {
printf("Result is 0\n");
free(result);
result = NULL; /* arguable */
fclose(infile);
return 0;
}
printf("Result is: %s\n", &result[count]);