trouble with malloc function: Critical error detected c0000374 - sparse-matrix

I am writing a program about sparse matrices with linked representation.
temp = (matrixPointer*)malloc(sizeof(matrixPointer));
However whenever I use malloc like above for a temporary pointer, it detects an error and stops. It's alright if I have less than 3 inputs, but an error when it becomes 3 or more. Why is this happening? It only says Critical error detected c0000374.
Here is part of my code.
for (i = 0; i < numTerms; i++) {
printf("Enter row, column and value: ");
scanf("%d%d%d", &row, &col, &value);
if (row > currentRow) {
last->right = hdnode[currentRow];
currentRow = row; last = hdnode[row];
}
temp = (matrixPointer*)malloc(sizeof(matrixPointer));
temp->tag = entry; temp->u.entry.row = row;
temp->u.entry.col = col;
temp->u.entry.value = value;
last->right = temp;
last = temp;
hdnode[col]->u.next->down = temp;
hdnode[col]->u.next = temp;
}

Probably related to 23471161. It might help to post more of your code, along with the output of a backtrace from your favorite debugging software.

Related

problem with dynamic array and pointers in selection sort

i make a program of selection sort using dynamic array and pointers but after running this code i found that array is being sorted if we give the size input like 4 and 6 but does't sort properly if the size input is like 5 and 7 etc ...i also did bubble sort program before this using same technique of pointers and dynamic array but it gave perfect sorted array in all the condition , i also try to debuge the code but still don't understand why this is happening if anyone having idea about this then please help me out .
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
int main()
{
int * ptr,temp,min;
int size,i,j,s;
printf("Enter the size of array:");
scanf("%d",&size);
ptr = (int *)(calloc (size,sizeof(int)));
if(ptr == NULL)
printf("No memory");
else
{
printf("\n=== RANDOM ELEMENTS OF ARRAY ===\n");
for(s=0;s<size;s++)
*(ptr+s) = rand()%100;
for(s=0;s<size;s++)
printf("\nElement [%d] = %d ",s,*(ptr+s));
// selection sort algorithm
for(i=0;i< size-1;i++)
{
min = i;
for(j=i+1;j<size;j++)
{
if(*(ptr+j) < *(ptr+min))
{
min = j;
}
temp = *(ptr+i);
*(ptr+i) = *(ptr+min);
*(ptr+min) = temp;
}
}
// End of algorithm
printf("\n\n======= SORTED ELEMENTS =======\n\n");
for(s=0;s<size;s++)
printf("Element [%d] = %d \n",s,*(ptr+s));
}
}
Your Selection Sort algorithm seems to be wrong. You have to replace the element in the current index with the minimum after the inner for loop finishes iteration:
for(i=0;i< size-1;i++)
{
min = i;
for(j=i+1;j<size;j++)
{
if(*(ptr+j) < *(ptr+min))
{
min = j;
}
}
temp = *(ptr+i);
*(ptr+i) = *(ptr+min);
*(ptr+min) = temp;
}
Now, it should work for all input sizes.
Clearing away a couple of unnecessary confusion factors...
*(ptr + index)
Is identical to
ptr[index]
But the second is much easier to read.
Next, in the following section the variable min is introduced,
if(*(ptr+j) < *(ptr+min))
{
min = j;
}
...but is not necessary for a simple sort. Just stick with i and j and the sort will proceed correctly for either even or odd sets of values. Finally, to eliminate the memory leak, call free(ptr); when ptr is no longer needed. Following is a cleaned up version, with corrections.
int main(void)//added void
{
int * ptr,temp/*,min*/;
int size,i,j,s;
printf("Enter the size of array:");
scanf("%d",&size);
ptr = calloc (size,sizeof(int));//casting is required in C++
//but unnecessary in C.
//(and can be problematic)
if(ptr == NULL)
{
printf("No memory");
}
else
{
printf("\n=== RANDOM ELEMENTS OF ARRAY ===\n");
for(s=0;s<size;s++)
ptr[s] = rand()%100;
for(s=0;s<size;s++)
printf("\nElement [%d] = %d ",s,ptr[s]);
// selection sort algorithm
for(i=0;i< size-1;i++)
{
for(j=i+1;j<size;j++)//removed if section introducing 'min'
{
if(ptr[j] < ptr[i])
{
temp = ptr[i];
ptr[i] = ptr[j];
ptr[j] = temp;
}
}
}
// End of algorithm
printf("\n\n======= SORTED ELEMENTS =======\n\n");
for(s=0;s<size;s++)
printf("Element [%d] = %d \n",s,*(ptr+s));
free(ptr);
}
return 0;//added
}
BTW, this was tested with size == 3 and
ptr[0] = 3;
ptr[1] = 2;
ptr[2] = 1;
along with several other odd and even counts of random values

Segmentation fault with concatenation of two strings

I'm trying to build alphanumeric strings consisting of 3 initial letters and 3 final numbers and save them in a .txt file. I wrote this:
int i = 0,
j = 0;
char name_cpu[8],
array_numbers_final[8],
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(list_cpu, "%s \n", name_cpu);
}
The problem is that at the first external for loop it correctly prints a string of the form "AAA000". At the second for loop it goes in segmentation fault. Can anyone tell me what and where I am doing wrong?
EDIT:
A minimal reproducible example is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void){
FILE *list_cpu = NULL;
int i = 0,
number_cpu = 3,
j = 0;
char name_cpu[8] = {0},
array_numbers_final[8] = {0},
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
list_cpu = fopen("list_cpu.txt", "w");
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(list_cpu, "%s \n", name_cpu);
}
fclose(list_cpu);
return(0);
}
If number_cpu is equal to 1 it works. But if it is higher then 1, the program goes into segmentation fault.
answer to new edits to OP
Edits to OP include initialization of variables addressing some instances of undefined behavior in original code, however buffer overflow problem remains in following section:
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(list_cpu, "%s \n", name_cpu);
}
fclose(list_cpu);
Where name_cpu is defined with 8 char: char name_cpu[8] = {0}
"If number_cpu is equal to 1 it works. But if it is higher then 1, the program goes into segmentation fault."...
After first iteration of outer loop, including one strcat of name_cpu and list_cpu, the char name_cpu is populated with 6 new characters and \0 in remaining locations. Eg:
//example
|S|J|P|Y|E|P|\0|\0| //
The error occurs at end of 2nd iteration of outer loop at the strcat() statement. The inner loop re-populated the first three positions of name_cpu, eg:
//first three positions changed, the rest remains
|C|B|A|Y|E|P|\0|\0| //
^ ^ ^ updated values
Error occurs when the new value for array_numbers_final :
|G|H|O|\0|\0|\0|\0|\0|
is attempted to be concatenated to name_cpu, resulting in:
|C|B|A|Y|E|P|G|H|O| //attempt to write to memory not owned
^end of buffer
Resulting in buffer overflow error, and likely the segmentation fault error condition.
Again, as before, design variables to meet the potential needs of of the program. In this instance the following will work:
char name_cpu[100] = {0};
char array_numbers_final[100] = {0};
answer to original post:
The problem is here:
strcat(name_cpu, array_numbers_final);//undefined behavior.
First, name_cpu[8] is uninitialized at time of declaration, nor is it initialized at any time before used. Because it is not guaranteed what the contents are, it is not necessarily a string. Using this variable as is in any string function can invoke undefined behavior
Furthermore,(even if name_cpu is a valid string) when array_numbers_final is concatenated to name_cpu, the buffer will overflow. During my test run I saw this:
The fix is to start off with initialized buffers of sufficient size for intended purpose. eg:
char name_cpu[100] = {0}
array_numbers_final[100] = {0},
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
Code example below is adaptation using your provided example, with suggested edits. Read in-line comments:
int main(void)
{
int number_cpu = 3;//added - previously not defined in OP
int i = 0,
j = 0;
char name_cpu[100] = {0},//resized and initialize
array_numbers_final[100] = {0},//resized and initialize
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(stdout, "%s \n", name_cpu);//to stdout
// ^ changed here
}
return 0;
}

Value changes in a struct when editing another struct in another function

I've run into a problem with structs which I believe is caused by incorrect mallocs, or possibly rather my reallocs. I've cut down the code as much as possible to only show what I believe could be relevant, so nearly all the actual operations are omitted.
The struct I have looks as follows:
struct poly_t {
int nvars, *factor, *exp;
};
The value that's acting weird is nvars, which to me would signify that I'm somehow not reserving memory properly. What I do is that I first have a function that creates and fills the struct, then I have another function where I send two of these structs in and create a third identical struct. When editing the value of nvars in this third struct, it very rarely also edits the value of nvars in the first struct. When running gdb, it shows the exact row it happens on is when I do thirdp->nvars++; in my mul function.
So with this function I create my first and second structs (a and b).
poly_t* new_poly_from_string(const char* a){
struct poly_t* p = malloc(sizeof(struct poly_t));
p->nvars = 0;
p->factor = malloc(strlen(a) * sizeof(int));
p->exp = malloc(strlen(a) * sizeof(int));
for (int i = 0; i < strlen(a); i++){
//do stuff to put a into p, using at most p->factor[p->nvars] and the same for p->exp
p->factor = realloc(p->factor, p->nvars*sizeof(int));
p->exp = realloc(p->exp, p->nvars*sizeof(int));
printf("%d", p->nvars); //At this point, nvars is the correct value
return p;
}
And below is the function that works in 9/10 cases but in some rare cases it doesn't. I've marked the exact row that changes a->nvars with an arrow -->.
poly_t* mul(poly_t* a, poly_t* b){
struct poly_t* thirdp = malloc(sizeof(struct poly_t));
thirdp->nvars = 0;
thirdp->factor = malloc((a->nvars + b->nvars) * sizeof(int));
thirdp->exp = malloc((a->nvars + b->nvars) * sizeof(int));
for (int i = 0; i < a->nvars; i++){
for (int j = 0; j < b->nvars; j++){
for (int k = 0; k < p->nvars; k++){
if (p->exp[k] == a->exp[i] + b->exp[j]){
p->factor[k] += a->factor[i]*b->factor[j];
found = 1;
break;
}
}
if (!found){
p->factor[p->nvars] = a->factor[i]*b->factor[j];
p->exp[p->nvars] = a->exp[i] + b->exp[j];
--> p->nvars++; //This is the row that changes a->nvars according to gdb
}
}
}
return thirdp;
}
Here's what I got when running gdb while trying to figure out what was changing a->nvars. Note that p is the same as thirdp above, I just renamed it here for clarity.
edit: Readded the actual code in the mul function
You are allocating space for the sum of the number of integers
a->nvars + b->nvars
I wonder what you do in
//fill thirdp->factor and thirdp->exp
As you have nested for loops I suspect you may be generating
a->nvars * b->nvars //multiply
items and hence running off the end of allocated space. You now show us the code and we see
if (!found){
// --- here ----
p->factor[p->nvars] = a->factor[i]*b->factor[j];
p->exp[p->nvars] = a->exp[i] + b->exp[j];
p->nvars++;
}
At the point I mark here you should check the value of p->nvars, I think it has the possibility to reach a value greater than (a->nvars + b->nvars).
I think to be safe allocate the space for (a->nvars * b->nvars) ints.
The problem was as I believed in the mallocs. Specifically the following two rows:
thirdp->factor = malloc((a->nvars + b->nvars) * sizeof(int));
thirdp->exp = malloc((a->nvars + b->nvars) * sizeof(int));
I simply wasn't allocating enough memory which caused the weird behaviour. What I wanted was:
thirdp->factor = malloc((a->exp[0] + b->exp[0]) * sizeof(int));
thirdp->exp = malloc((a->exp[0] + b->exp[0]) * sizeof(int));
Unfortunately since I didn't give any of the indata, or really much context, you guys probably couldn't have figured that out <.< Sorry!

Function Warnings in C

Hello guys i have threefunctions for which i get 4 warnings...!!
The first one is this
void evaluatearxikos(void)
{
int mem;
int i;
double x[NVARS+1];
FILE *controlpointsarxika;
controlpointsarxika = fopen("controlpointsarxika.txt","r");
remove("save.txt");
for(mem = 0; mem < POPSIZE; mem++)
{
for(i = 0; i < NVARS; i++)
{
x[i+1] = population[mem].gene[i];
}
rbsplinearxiki();
XfoilCall();
population[mem].fitness = FileRead();
remove("save.txt");
}
fclose(controlpointsarxika);
}
For this one the compiler warns me tha variable x is set but not used...!! But actually i am using the variable x...!!!
The second function is this one...
void elitist(void)
{
int i;
double best,worst;
int best_mem,worst_mem;
best = population[0].fitness;
worst = population[0].fitness;
for(i = 0; i < POPSIZE - 1; i++)
{
if(population[i].fitness > population[i+1].fitness)
{
if(population[i].fitness >= best)
{
best = population[i].fitness;
best_mem = i;
}
if(population[i+1].fitness <= worst)
{
worst = population[i+1].fitness;
worst_mem = i+1;
}
}
else
{
if(population[i].fitness <= worst)
{
worst = population[i].fitness;
worst_mem = i;
}
if(population[i+1].fitness >= best)
{
best = population[i+1].fitness;
best_mem = i+1;
}
}
}
if(best >= population[POPSIZE].fitness)
{
for(i = 0; i < NVARS; i++)
{
population[POPSIZE].gene[i] = population[best_mem].gene[i];
}
population[POPSIZE].fitness = population[best_mem].fitness;
}
else
{
for(i = 0; i < NVARS; i++)
{
population[worst_mem].gene[i] = population[POPSIZE].gene[i];
}
population[worst_mem].fitness = population[POPSIZE].fitness;
}
}
For this one i get two warnings that the variables worst_mem and best_mem may be used uninitialized in this function..!! But i initialize values to both of them..!!
And the third function is this...
void crossover(void)
{
int mem,one;
int first = 0;
double x;
for(mem =0; mem < POPSIZE; mem++)
{
x = rand()%1000/1000;
if(x < PXOVER)
{
first++;
if(first%2 == 0)
{
random_Xover(one,mem);
}
else
{
one = mem;
}
}
}
}
For which i get that the variable one may be used unitialized..!! But it is initialized..!
Can you please tell me what is wrong with these functions...??
Thank you in advance
In your first function, you set (assign) x, but you never read it, hence you are not using it... you're only wasting CPU cycles by writing to it. (Note also that because you index it as i+1 you write beyond the space you've allocated for it).
In the second function, your initializations to those variables are in conditional blocks. You can see that (perhaps? I didn't verify) in all conditions they are initialized but your compiler isn't that smart.
In your third function, it does appear that one could be refered to without having first been initialized.
First: You set x but do not use it. It's a local variable that gets set but it's dropped as soon as the function returns.
Second: There might be values that makes it so that your best_mem/worst_mem never gets set in your if/else, but you are using them later on. If they haven't been set, they contain garbage if not initialized.
Third: While it shouldn't happen that you try to use an uninitialized variable in your code, it still looks weird and compiler doesn't see that it won't happen first time.
When you get compiler warnings, treat is as you are doing something wrong or rather not recommended and that it could be done in a better way.
The x variable is only used on the left hand side (i.e. assigned a value). You are not using that value on the right hand side or pass it to a function.
It may be possible to get to the end of the loop for(i = 0; i < POPSIZE - 1; i++) without those variables given a value. Why not set them in the declaration.
The call to random_Xover(one,mem); could be called when one is not set. Change the line int mem,one; to int mem,one = <some value>;

What's wrong in this C program..?

struct bucket
{
int nStrings; //No. of Strings in a Bucket.
char strings[MAXSTRINGS][MAXWORDLENGTH]; // A bucket row can contain maximum 9 strings of max string length 10.
};//buck[TOTBUCKETS];
void lexSorting(char array[][10], int lenArray, int symb) //symb - symbol, sorting based on character symbols.
{
int i, j;
int bucketNo;
int tBuckNStrings;
bucket buck[TOTBUCKETS];
for(i=0; i<lenArray; i++)
{
bucketNo = array[i][symb] - 'a'; // Find Bucket No. in which the string is to be placed.
tBuckNStrings = buck[bucketNo].nStrings; // temp variable for storing nStrings var in bucket structure.
strcpy(buck[bucketNo].strings[tBuckNStrings],array[i]); // Store the string in its bucket.
buck[bucketNo].nStrings = ++tBuckNStrings; //Increment the nStrings value of the bucket.
}
// lexSorting(array, lenArray, ++symb);
printf("****** %d ******\n", symb);
for(i=0; i<TOTBUCKETS; i++)
{
printf("%c = ", i+'a');
for(j=0; j<buck[i].nStrings; j++)
printf("%s ",buck[i].strings[j]);
printf("\n");
}
}
int main()
{
char array[][10] = {"able","aback","a","abet","acid","yawn","yard","yarn","year","yoke"};
int lenArray = 10;
int i;
printf("Strings: ");
for(i=0; i<lenArray; i++)
printf("%s ",array[i]);
printf("\n");
lexSorting(array, lenArray, 0);
}
Well here is the complete code, that I am trying. since its been a long time since i have touched upon C programming, so somewhere i am making mistake in structure declaration.
The problem goes here:-
1) I have declared a structure above and its object as array(buck[]).
2) Now when I declare this object array along with the structure, it works fine.. I have commented this thing right now.
3) But when I declare this object array inside the function.. because ultimately i have to declare inside function( as i need to build a recursive program, where objects will be created in very recursive call) then the program is throwing segmentation fault.
Expected Output
> [others#centos htdocs]$ ./a.out
> Strings: able aback a abet acid yawn
> yard yarn year yoke
> ****** 0 ******
> a = able aback a abet acid
> b =
> c
> .
> .
> y = yawn yard yarnyear yoke
> z =
Actual Output
[others#centos htdocs]$ ./a.out
Strings: able aback a abet acid yawn yard yarn year yoke
Segmentation fault
I have no idea, what difference I made in this. Kindly help.
Thanks.
What's wrong with your program is that it doesn't contain a main() function hence it won't link.
Beyond that, you should always do the following when asking questions here:
Provide a complete, minimal code sample that demonstrates the problem.
Detail the expected behaviour.
Detail the actual behaviour.
In fact, when I add the line:
int main (void) { return 0; }
it compiles and links fine.
That means it's almost certainly a run-time error you're experiencing hence we need the main() to figure out what you're doing wrong.
Using my psychic debugging skills, an important difference between declaring it at file scope and block scope is that the file-scope version will be initialised to zeros.
That means all the structure fields will be effectively zero (for the count) and empty strings (for the strings). With block scope, those counts and strings will be uninitialised.
The fact that you're using TOBUCKETS to print the structure out probably means you're trying to print out one of those uninitialised strings.
I think what's probably happening is that the nStrings field contains a garbage value when you start the processing. You should probably initialise it to zero manually (with a loop) and see if that fixes your problem. Put this after the declaration of buck in your sort function:
for (i = 0; i < TOTBUCKETS; i++)
buck[i].nStrings = 0;
Right. It turns out that was the problem. When I fix up the errors in your latest code, I get the segmentation violation as well but, when I add that section above, it works fine:
#include <stdio.h>
#include <string.h>
#define MAXSTRINGS 9
#define MAXWORDLENGTH 10
#define TOTBUCKETS 26
struct bucket
{
int nStrings;
char strings[MAXSTRINGS][MAXWORDLENGTH];
};
void lexSorting(char array[][10], int lenArray, int symb)
{
int i, j;
int bucketNo;
int tBuckNStrings;
struct bucket buck[TOTBUCKETS];
for(i=0; i<TOTBUCKETS; i++) buck[i].nStrings = 0;
for(i=0; i<lenArray; i++)
{
bucketNo = array[i][symb] - 'a';
tBuckNStrings = buck[bucketNo].nStrings;
strcpy(buck[bucketNo].strings[tBuckNStrings],array[i]);
buck[bucketNo].nStrings = ++tBuckNStrings;
}
printf("****** %d ******\n", symb);
for(i=0; i<TOTBUCKETS; i++)
{
printf("%c = ", i+'a');
for(j=0; j<buck[i].nStrings; j++)
printf("%s ",buck[i].strings[j]);
printf("\n");
}
}
int main()
{
char array[][10] = {"able","aback","a","abet","acid",
"yawn","yard","yarn","year","yoke"};
int lenArray = 10;
int i;
printf("Strings: ");
for(i=0; i<lenArray; i++)
printf("%s ",array[i]);
printf("\n");
lexSorting(array, lenArray, 0);
}
The output of that was:
Strings: able aback a abet acid yawn yard yarn year yoke
****** 0 ******
a = able aback a abet acid
b =
c =
d =
e =
f =
g =
h =
i =
j =
k =
l =
m =
n =
o =
p =
q =
r =
s =
t =
u =
v =
w =
x =
y = yawn yard yarn year yoke
z =
keyword struct is not required when you create objects for it.

Resources