My task is to allocate memory for an array of integers (n elements), to give random values to each one of them and to print them sorted and unsorted. When I compile the code, I get this warning "'v' is used uninitialized in this function", and when I try to run it, I get "Segmentation fault".
I was wondering why am I supposed to initialize the array if I want to fill it up with random values? Is there a problem in the way I allocate memory for the array?(I'm not sure about the cast i did)
This is the source code:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main() {
int i, j, max, n, *v, aux;
scanf("%d%d", &n, &max);
*v=(int*)malloc(n*sizeof(int));
for(i=0; i<n; i++){
srand(time(NULL));
v[i]=rand()%max;
}
for(i=0; i<n; i++){
printf("%d ", v[i]);
}
printf("\n");
for(i=0; i<n-1; i++){
for(j=0; j<n-i-1; j++){
if(v[j]>v[j+1]){
aux=v[j];
v[j]=v[j+1];
v[j+1]=aux;
}
}
}
for(i=0; i<n; i++){
printf("%d ", v[i]);
}
printf("\n");
return 0;
}
I would be grateful if someone could make me understand what I do wrong, and eventually modify part of the source.
You made a typo (I presume) when creating the array.
*v=(int*)malloc(n*sizeof(int));
should be
v=(int*)malloc(n*sizeof(int));
The warning
'v' is used uninitialized in this function
is because of the deferencing *v in the line above.
Here's your problem:
*v=(int*)malloc(n*sizeof(int));
You assign the address of your allocated memory to the dereference of v - that is, you dereference your uninitialized pointer, and write to "wild memory".
In addition, using unitialized values is still a rotten way to get randomness. Look up rand() in your manual.
Related
This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 11 months ago.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i,j;
int (*a)[3]=NULL;
for(i=0; i<4;i++)
{
for(j=0; j<3;j++)
{
scanf("%d", *(a+i)+j);
}
}
for(i=0; i<4;i++)
for(j=0; j<3;j++)
printf("%5d", a[i][j]);
printf("\n");
return 0;
}
I have a problem with my C code above, which is trying to print a multi-dimensional array on screen. When running this code, a message of segmentation fault is sent to me and I don't know how to fix that.
The segmentation fault is due to the null pointer int (*a)[3]=NULL.
Either: allocate it dynamically (in this case, you have to free it when done with it):
int (*a)[3] = malloc(sizeof *a * 4);
or declare it static:
int a[4][3];
Also, you are missing some curly braces:
for(i=0; i<4;i++) { // This one
for(j=0; j<3;j++)
printf("%5d", a[i][j]);
printf("\n");
} // And this one
In Java, you can use Scanner.nextInt to get the next input value. I have tried doing this is C:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("How long is your array?");
int len;
scanf("%d",&len);
printf("Enter %d numbers:",len);
int array[len];
for (int i=0; i<len; i++){
scanf("%d", &array[i]);
}
for (int i=0; i<len; i++){
printf(array[i]);}
return 0;
}
But it will stop before printing the array, which makes me think that this is a false methode.
[Note: The question was edited after this answer was written.]
printf(array); will not work. You must print the array elements individually, using a loop similar to the one you used to read the values. C has very limited facilities for automatically working with aggregates.
Additionally, scanf("%d", array[i]); must be scanf("%d", &array[i]);. You need to tell scanf where to put the value it reads. Passing array[i] would tell scanf what the current value is. &array[i] is the address of where array[i] is. (When using printf, you will pass array[i], because printf only needs the value to print. It does not need to know where it is.)
This code is meant to find intersection and union of two unsorted arrays which may contain duplicates.
The union works fine, but when trying to access intersection array memory, I get garbage results.
I can't find out where the problem is, tried to debug it but it didn't help me much either.
note: remember[] is an array of flags that saves indices of intersection elements in two arrays.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i,n1,n2,j;
int user1[20];
int unionSize;
int intersectionArraySize;
printf("enter array1 size::\n");
scanf("%d",&n1);
printf("array1: ");
for(i=0; i<n1; i++)
{
scanf("%d",&user1[i]);
if (i>0) if(user1[i]==user1[i-1]) user1[i-1]=user1[i];
}
int user2[20];
printf("enter array2 size::\n");
scanf("%d",&n2);
for(i=0; i<n2; i++)
{
scanf("%d",&user2[i]);
if (i>0) if(user2[i]==user2[i-1]) user2[i-1]=user2[i];
}
int unionArray[20];
int remember[20]= {0}; // save index of common elements btn 2 arrays
int intersectionArray[20]={0};
intersectionArraySize=0;
unionSize=n1;
int index=0;
for(i=0; i<n1; i++)
{
for(j=0; j<n2; j++)
{
if (user1[i]==user2[j])
{
remember[j]=1;
intersectionArray[index]==user1[i];
intersectionArraySize++;
index++;
}
else unionArray[i]=user1[i];
}
}
for(i=0; i<n2; i++)
{
if(remember[i]!=1)
{
unionArray[n1]=user2[i];
n1++;
unionSize++;
}
}
printf("Union: ");
for (i=0; i<unionSize; i++)
{
if(i==unionSize-1) printf("%d\n",unionArray[i]);
else printf("%d ,",unionArray[i]);
}
printf("intersection: ");
for (i=0; i<intersectionArraySize; i++)
{
if(i==intersectionArraySize-1) printf("%d\n",intersectionArray[i]);
else printf("%d ,",intersectionArray[i]);
}
return 0;
}
Here's the problem:
intersectionArray[index]==user1[i];
It should be:
intersectionArray[index]=user1[i];
General comments on your code:
It's pretty bad designed. For instance, unless you have a very good reason, do not calculate both at the same time. Have one block that does intersection and only that. Same for union.
You declare the arrays with a fixed size, which is a bit weird since you ask for the sizes. Not a very big deal, but be aware of dangers if you enter a size over 20.
What's worse is that unionArray has a size of 20. It should be 40.
index and intersectionArraySize is practically the same variable. Get rid of one.
This looks messy:
for (i=0; i<unionSize; i++) {
if(i==unionSize-1) printf("%d\n",unionArray[i]);
else printf("%d ,",unionArray[i]);
}
Do like this:
for (i=0; i<unionSize-2; i++) {
printf("%d ,",unionArray[i]);
}
printf("%d\n", unionArray[unionSize-1]);
Also not a very big deal, but why do a conditional check on every single element when you know that it is the last that should be treated specially?
The following C code assigns a pointer to an array:
#include <stdio.h>
// ders 5 : Diziler vs. Isaretciler
int main(){
int array[20];
int i;
int* pointer = (int* )array;
// Fill the array with numbers from 0 to 20
for (i=1; i<=20; i++){
array[i] = i;
}
printf("5th element of the array: %d \n", array[4]);
printf("array: %d pointer: %d \n",array,pointer);
printf("The value pointed with (pointer+4) %d \n", *(pointer+4));
}
That "pointer" must be equal to the "array" by value, but it is not. So it gives an error and collapses. I work with BloodShed Dev C++ IDE (but the program is in C).
for (i=1; i<=20; i++){
C (and many other languages) starts index with zero. It shoule be the follows:
for (i=0; i<20; i++){
About the concept:
Array is not pointer. It decays into pointer in particular context, and the decayed value is the address of the first element of the array.
You don;t need to explicitly cast int* pointer = (int* )array; as int* pointer = array; itself returns the address of the first element which is same as the base address of the array.
Since you have declared the pointer to be int you can increment the pointer to access the next array value.
Also, in C the indexes start from zero so better having a loop starting from
for (i=0; i<20; i++){ which is the problem of your application crash. As C does not have boundary check and will call the value which is beyond the value allocated, it will throw a segmentation fault.
Try this
#include <stdio.h>
int main(){
int array[21];
int i;
int* pointer = array;
// Fill the array with numbers from 0 to 20
for (i=0; i<=20; i++){
array[i] = i;
}
printf("5th element of the array: %d \n", array[4]);
printf("array: %d pointer: %d \n",*array,*pointer);
printf("The value pointed with (pointer+4) %d \n", *(pointer+4));
}
I cant seem to find out where i'm going wrong in C. its on line 37 it says assignment to expression with array type any help or advice would be great thanks.
I was wondering also is it something to do with not adding in the brackets to show that they're arrays on line 37 but when i put them in it displays more errors
/*
This program uses pass by reference to calculate the values after two arrays are multiplied by each other
16/02/2015
Jake Young
*/
#include <stdio.h>
#define size 5
//Prototype
int multiply_function(int *[], int *[]);
main()
{
int array1[size];
int array2[size];
int i;
int answer[size];
//get users input for array1
printf("Please enter %d values into array1:\n", size);
for(i=0; i<size; i++)
{
scanf("%d", &array1[i]);
}//end for loop
//get users input for array2
printf("Please enter %d values into array2:\n", size);
for(i=0; i<size; i++)
{
scanf("%d", &array2[i]);
}//end for loop
//call function()
answer=multiply_function(&array1, &array2); // line 37
//Print out the results from array1 multiplied by array2
printf("Array1 multiplied by Array2 is the following:\n");
for(i=0; i<size; i++)
{
printf("%d multiplied by %d is %d\n", array1[i], array2[i], answer[i]);
}//end for loop
}//end main()
multiply_function(int *array1[], int *array2[])
{
int *answer[size];
int i;
for(i=0; i<size; i++)
{
//calculate multiplication
*answer[i]= *array1[i]* *array2[i];
}//end for loop
return(*answer);
}//end function()
int multiply_function(int *[], int *[]);
This doesn't make any sense. You intend to pass arrays of integers to the function, not arrays of pointers. You'll have to study how arrays should be passed to functions.
main()
This form is not standard. Unless you are programming a "bare metal" embedded system, you should use int main (void).
answer=multiply_function(&array1, &array2);
This doesn't make any sense. You declared the function to return an int. Again, study how arrays are passed to and from a function. Furthermore, you can't copy arrays with the assignment operator: you have to use memcpy() or similar functions.
multiply_function(int *array1[], int *array2[])
The function definition is different than the prototype: that is always bad practice. Apart from that, the function doesn't make any sense, as already mentioned.
int *answer[size];
This doesn't make any sense, you are declaring an array of pointers where you want an array of integers.
return(*answer);
Returning a pointer to a local variable in C is always a bug. And you can't return arrays like this. And there is no need for the parenthesis.
OK, you should really invest some more time to study arrays, pointers and fundamentals of functions in C.
Apart from grammatical problems in the code, the fundamental problem in this code is the answer[] array. it is defined both in main() and the multiply_function(). What you must do is to pass this array to the multiply_function() and have the function fill in the array.
I'm giving the solution below, with the hope that you'll compare it to your version and study the differences and continue to learn the basics of C:
#include <stdio.h>
#define size 5
//Prototype
int multiply_function(int *, int *, int *);
main()
{
int array1[size];
int array2[size];
int i;
int answer[size];
//get users input for array1
printf("Please enter %d values into array1:\n", size);
for(i=0; i<size; i++)
{
scanf("%d", &array1[i]);
}//end for loop
//get users input for array2
printf("Please enter %d values into array2:\n", size);
for(i=0; i<size; i++)
{
scanf("%d", &array2[i]);
}//end for loop
//call function()
multiply_function(array1, array2, answer);
//Print out the results from array1 multiplied by array2
printf("Array1 multiplied by Array2 is the following:\n");
for(i=0; i<size; i++)
{
printf("%d multiplied by %d is %d\n", array1[i], array2[i], answer[i]);
}//end for loop
}//end main()
multiply_function(int *array1, int *array2, int *answer)
{
int i;
for(i=0; i<size; i++)
{
//calculate multiplication
answer[i]= array1[i] * array2[i];
}//end for loop
return(*answer);
}//end function()