issue with qsort in c - c

I have a structure like this :
typedef struct item{
char label[10];
int support;
};
I created an array of such structures like this :
struct item* finstr = (struct item*)malloc(sizeof(struct item)*10);
I filled the array with appropriate values and want to sort the array according to the values of 'support', using the qsort function. But, the array is not getting sorted at all. The output is coming out to be the same as input.
here is the call to the qsort function and the code for the 'comparator' function :
qsort((void*)finstr,(sizeof(finstr)/sizeof(finstr[0])),sizeof(finstr[0]),comparator);
comparator function :
int comparator(const void* i1,const void* i2) {
int l = ((struct item*)i1)->support;
int r = ((struct item*)i2)->support;
return l-r;
}
I do not understand where I am making the mistake. Any help is greatly appreciated.
Thanks in advance.

The expression (sizeof(finstr)/sizeof(finstr[0])) does not give you the number of elements unless finstr is an array. In your case, it evaluates to sizeof(void*)/sizeof(struct item), which is most likely 0.
Replace it with 10.
Excellent advice from #ForhadAhmed:
Its good practice to replace the 10 in malloc(sizeof(struct item)*10) and the size of the array passed to the qsort function with a macro or a variable so that you don't accidentally call qsort with a different sized array than what you intended.

Try building and running the following, to see what answer you get:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char bar[123];
int baz;
} foo;
int main(int argc, char** argv) {
foo *foo_ptr = malloc(sizeof(foo) * 1000);
fprintf(stdout, "%zu\n", sizeof(foo_ptr));
fprintf(stdout, "%zu\n", sizeof(foo_ptr[0]));
free(foo_ptr);
return 0;
}
Depending on architecture, you may notice that sizeof(foo_ptr) is eight bytes — the size of the foo pointer called foo_ptr. Compare this with the value of sizeof(foo_ptr[0]). This should provide a hint at what is wrong.

Related

Different places get different values [duplicate]

This question already has answers here:
C sizeof a passed array [duplicate]
(7 answers)
Closed 4 years ago.
In the program below the length of the array ar is correct in main but in temp it shows the length of the pointer to ar which on my computer is 2 (in units of sizeof(int)).
#include <stdio.h>
void temp(int ar[]) // this could also be declared as `int *ar`
{
printf("%d\n", (int) sizeof(ar)/sizeof(int));
}
int main(void)
{
int ar[]={1,2,3};
printf("%d\n", (int) sizeof(ar)/sizeof(int));
temp(ar);
return 0;
}
I wanted to know how I should define the function so the length of the array is read correctly in the function.
There is no 'built-in' way to determine the length inside the function. However you pass arr, sizeof(arr) will always return the pointer size. So the best way is to pass the number of elements as a seperate argument. Alternatively you could have a special value like 0 or -1 that indicates the end (like it is \0 in strings, which are just char []).
But then of course the 'logical' array size was sizeof(arr)/sizeof(int) - 1
Don't use a function, use a macro for this:
//Adapted from K&R, p.135 of edition 2.
#define arrayLength(array) (sizeof((array))/sizeof((array)[0]))
int main(void)
{
int ar[]={1,2,3};
printf("%d\n", arrayLength(ar));
return 0;
}
You still cannot use this macro inside a function like your temp where the array is passed as a parameter for the reasons others have mentioned.
Alternative if you want to pass one data type around is to define a type that has both an array and capacity:
typedef struct
{
int *values;
int capacity;
} intArray;
void temp(intArray array)
{
printf("%d\n", array.capacity);
}
int main(void)
{
int ar[]= {1, 2, 3};
intArray arr;
arr.values = ar;
arr.capacity = arrayLength(ar);
temp(arr);
return 0;
}
This takes longer to set up, but is useful if you find your self passing it around many many functions.
As others have said the obvious solution is to pass the length of array as parameter, also you can store this value at the begin of array
#include <stdio.h>
void temp(int *ar)
{
printf("%d\n", ar[-1]);
}
int main(void)
{
int ar[]= {0, 1, 2, 3};
ar[0] = sizeof(ar) / sizeof(ar[0]) - 1;
printf("%d\n", ar[0]);
temp(ar + 1);
return 0;
}
When you write size(ar) then you're passing a pointer and not an array.
The size of a pointer and an int is 4 or 8 - depending on ABI (Or, as #H2CO3 mentioned - something completely different), so you're getting sizeof(int *)/sizeof int (4/4=1 for 32-bit machines and 8/4=2 for 64-bit machines), which is 1 or 2 (Or.. something different).
Remember, in C when pass an array as an argument to a function, you're passing a pointer to an array.If you want to pass the size of the array, you should pass it as a separated argument.
I don't think you could do this using a function. It will always return length of the pointer rather than the length of the whole array.
You need to wrap the array up into a struct:
#include<stdio.h>
struct foo {int arr[5];};
struct bar {double arr[10];};
void temp(struct foo f, struct bar g)
{
printf("%d\n",(sizeof f.arr)/(sizeof f.arr[0]));
printf("%d\n",(sizeof g.arr)/(sizeof g.arr[0]));
}
void main(void)
{
struct foo tmp1 = {{1,2,3,4,5}};
struct bar tmp2;
temp(tmp1,tmp2);
return;
}
Inside the function ar is a pointer so the sizeof operator will return the length of a pointer. The only way to compute it is to make ar global and or change its name. The easiest way to determine the length is size(array_name)/(size_of(int). The other thing you can do is pass this computation into the function.

C: why should I declare a pointer?

It seems there are many questions of the form "should I declare X?" but not this specific one. I hope it is ok to ask this.
The title says it all: why should I declare a pointer? Even better: there are risks if I do not declare the pointer? Consider the following examples:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <string.h>
void func(int *ptr);
int main (int argc, char **argv)
{
int a;
int *PTRa;
a = -1;
PTRa = &a;
func(PTRa);
printf("%d\n", a);
return 0;
}
void func(int *ptr)
{
*ptr = 1;
return;
}
I get a=1. In this case I would say the pointer is declared (and assigned as well): I have the line int *PTRa; (declaration) and the line PTRa = &a; (assignment). The results is correct. I don't get any warning.
Imagine now to replace the main with the following:
int main (int argc, char **argv)
{
int a;
a = -1;
func(&a);
printf("%d\n", a);
return 0;
}
Here I do not declare the pointer but just give the address of a to func. The result is correct and I don't get warnings.
My understanding is that the two approaches are identical: func always gets the same input, the address of a. I would even dare to say that I feel the second approach to be better, as I feel it to be clearer and I feel the variable PTRa to be useless and somewhat redundant. However, I always see codes where the first approach is used and I have the feeling I will be told to do so. Why?
You are correct: there's no point in declaring a pointer in your example. A pointer is just a variable that holds an address. The cleaner approach is to pass directly the address of the variable: func(&a) instead of doing one extra step and declaring PTRa.
Note that not all cases are this simple. For example, if you want to have an array of ints, but you want to be able to grow that array dynamically because you don't know how big it should be you have to declare a pointer:
int count = ...; // get the count from the user, from a file, etc
int *list_of_ints = malloc(sizeof(int) * count);
if (list_of_ints == NULL)
{
// malloc failed.
printf("Not enough memory!\n");
exit(1);
}
// Now `list_of_ints` has enough space to store exactly `count` `int`s
EDIT: as #paulsm4 pointed out in a comment, the question Why use pointers? is a great source of information related to this topic.
EDIT 2: one good reason to want a pointer to the address of a variable might be that you want a pointer inside a structure or array:
struct foo
{
int x;
};
struct bar
{
int y;
struct foo f;
};
struct bar b;
struct foo *ptr_foo = &b.f;
You can now work more easily with b.f because you're just working with a struct foo.
In this case there's no benefit in creating a separate pointer variable.
It might be necessary in more complex cases, just like it's sometimes necessary to create variables of any other type.
From the title, I thought you're talking about pointer type, but actually, you are asking if declaring a variable is needed.
Variable is a piece of memory, storing some numbers(bytes), and the type of the variable, indicating how you and your program interpret those bytes: integer? float? character? etc.
Pointer is the memory address, it could be of a variable, or a function, or something else.
A variable of pointer is a small area in the memory, storing the address of other(or even same) memory.
You decide if you need an extra variable to store the pointer. It's the same to the decision that if you want a variable to store an integer:
int v = -1;
abs(v); // use variable
abs(-1); // use constant

Printf not showing and return value 3221225477

New to C and programming in general, so I am having kind of a tough time with structs when combined with arrays and pointers. I'm trying to create a struct with attempts, then create an array pointer (towards the struct) repeating it 10 times. Then find the average for every struct and print it.
Everything seems to work normally providing a return value of 0 until the loop.
#include <stdio.h>
#include <stdlib.h>
typedef struct Tries {
float attempts1;
float attempts2;
float attempts3;
float aver;
}Try;
int main(int argc, char *argv[]) {
int i,size=10,at1,at2,at3;
Try** arrayofTries= malloc (sizeof(Try)*size);
for (i=0;i<size;i++){
arrayofTries[i]->attempts1= rand () %(900 - 700)+700;
arrayofTries[i]->attempts2= rand () %(900 - 700)+700;
arrayofTries[i]->attempts3= rand () %(900 - 700)+700;
at1= arrayofTries[i]->attempts1;
at2= arrayofTries[i]->attempts2;
at3=arrayofTries[i]->attempts3;
arrayofTries[i]->aver = (at1+at2+at3)/3;
printf ("The average of %d person is%f",i,arrayofTries[i]->aver);
}
return 0;
}
arrayofTries should be of type Try * not Try **
Try *arrayofTries = malloc (sizeof(Try) * size);
So all your -> should be simple dots ..
You are allocating a pointer to pointer to Try but not allocating the direct pointer to the elements themselves. It looks like your intent is to declare a 1D array, not a 2D array, so what you should do is change the type of arrayofTries from Try ** to Try *.
Also, when you're done using memory allocated with malloc, free it:
free(arrayofTries);
arrayofTries = NULL;

How to correctly pass a pointer to an array of pointers?

In my code I need to pass a pointer to an array of pointers as a function argument. Code snippets:
struct foo * foos[] = {NULL, NULL, NULL};
some_function(&foos);
and:
static void some_function(struct foo ** foos) {
foos[0] = get_a_foo();
/* some more code here */
}
This works as expected (after some_function() returns, foos[] contains the pointers I set there), but I get a compiler warning for the call to some_function():
note: expected ‘struct foo **’ but argument is of type ‘struct foo * (*)[3]’
What’s the correct way to accomplish what I want (i.e. pass a pointer to the array of pointers to the function, so that the function can change pointers in the array)?
Pass it as some_function(foos)
struct foo ** is a pointer to a (single) pointer to a struct foo, not a pointer to an array of pointers, hence the compiler warning.
An easy way to silence the compiler warning is to call the function as follows:
some_function(&foos[0]);
This will pass a pointer to the first member, i.e. a struct foo **, rather than to the whole array; the address is the same in both cases.
If I understand what you are trying to do (fill your array of pointers with a call to a function), then your understanding of how to accomplish that is a bit unclear. You declare foos, which itself is an array. (an array of what? pointers).
You can treat it just like you would treat an array of char (from the standpoint that you can simply pass the array itself as a parameter to a function and operate on the array within a function) You can do that and have the changes visible in the caller because despite the array address itself being a copy in the function, the values it holds (the individual pointer address) remains the same.
For example:
#include <stdio.h>
char *labels[] = { "my", "dog", "has", "fleas" };
void fillfoos (char **f, int n)
{
int i;
for (i = 0; i < n; i++)
f[i] = labels[i];
}
int main (void) {
char *foos[] = { NULL, NULL, NULL };
int i, n = sizeof foos / sizeof *foos;
fillfoos (foos, n);
for (i = 0; i < n; i++)
printf ("foos[%d] : %s\n", i, foos[i]);
return 0;
}
Above foos is simply treated as an array passed to the function fillfoos which then loops over each pointer within foos filling it with the address to the corresponding string-literal contained in labels. The contents of foos is then available back in main, e.g.
Example Use/Output
$ ./bin/fillptp
foos[0] : my
foos[1] : dog
foos[2] : has
If I misunderstood your question, please let me know and I'm happy to help further.
You need a pointer to an array as clearly mentioned in the warning.
Below is a minimal code sample that explains the same.
#include<stdio.h>
typedef struct foo{
}FOO;
static void some_function(FOO* (*foos)[]) {
// foos above is a pointer to an array of pointers.
// Refer the link to start with a simple example.
// Access it like foos[0][0] which is the same as (*foos)[0]
/* some more code here */
}
int main(int argc, char **argv) {
FOO* foos[]={0,0,0}; // Here you have an array of pointers
some_function(&foos);
}

Segmentation fault (core dumped) when executing programs dynamically in c [duplicate]

This question already has answers here:
C sizeof a passed array [duplicate]
(7 answers)
Closed 4 years ago.
In the program below the length of the array ar is correct in main but in temp it shows the length of the pointer to ar which on my computer is 2 (in units of sizeof(int)).
#include <stdio.h>
void temp(int ar[]) // this could also be declared as `int *ar`
{
printf("%d\n", (int) sizeof(ar)/sizeof(int));
}
int main(void)
{
int ar[]={1,2,3};
printf("%d\n", (int) sizeof(ar)/sizeof(int));
temp(ar);
return 0;
}
I wanted to know how I should define the function so the length of the array is read correctly in the function.
There is no 'built-in' way to determine the length inside the function. However you pass arr, sizeof(arr) will always return the pointer size. So the best way is to pass the number of elements as a seperate argument. Alternatively you could have a special value like 0 or -1 that indicates the end (like it is \0 in strings, which are just char []).
But then of course the 'logical' array size was sizeof(arr)/sizeof(int) - 1
Don't use a function, use a macro for this:
//Adapted from K&R, p.135 of edition 2.
#define arrayLength(array) (sizeof((array))/sizeof((array)[0]))
int main(void)
{
int ar[]={1,2,3};
printf("%d\n", arrayLength(ar));
return 0;
}
You still cannot use this macro inside a function like your temp where the array is passed as a parameter for the reasons others have mentioned.
Alternative if you want to pass one data type around is to define a type that has both an array and capacity:
typedef struct
{
int *values;
int capacity;
} intArray;
void temp(intArray array)
{
printf("%d\n", array.capacity);
}
int main(void)
{
int ar[]= {1, 2, 3};
intArray arr;
arr.values = ar;
arr.capacity = arrayLength(ar);
temp(arr);
return 0;
}
This takes longer to set up, but is useful if you find your self passing it around many many functions.
As others have said the obvious solution is to pass the length of array as parameter, also you can store this value at the begin of array
#include <stdio.h>
void temp(int *ar)
{
printf("%d\n", ar[-1]);
}
int main(void)
{
int ar[]= {0, 1, 2, 3};
ar[0] = sizeof(ar) / sizeof(ar[0]) - 1;
printf("%d\n", ar[0]);
temp(ar + 1);
return 0;
}
When you write size(ar) then you're passing a pointer and not an array.
The size of a pointer and an int is 4 or 8 - depending on ABI (Or, as #H2CO3 mentioned - something completely different), so you're getting sizeof(int *)/sizeof int (4/4=1 for 32-bit machines and 8/4=2 for 64-bit machines), which is 1 or 2 (Or.. something different).
Remember, in C when pass an array as an argument to a function, you're passing a pointer to an array.If you want to pass the size of the array, you should pass it as a separated argument.
I don't think you could do this using a function. It will always return length of the pointer rather than the length of the whole array.
You need to wrap the array up into a struct:
#include<stdio.h>
struct foo {int arr[5];};
struct bar {double arr[10];};
void temp(struct foo f, struct bar g)
{
printf("%d\n",(sizeof f.arr)/(sizeof f.arr[0]));
printf("%d\n",(sizeof g.arr)/(sizeof g.arr[0]));
}
void main(void)
{
struct foo tmp1 = {{1,2,3,4,5}};
struct bar tmp2;
temp(tmp1,tmp2);
return;
}
Inside the function ar is a pointer so the sizeof operator will return the length of a pointer. The only way to compute it is to make ar global and or change its name. The easiest way to determine the length is size(array_name)/(size_of(int). The other thing you can do is pass this computation into the function.

Resources