Unable to get proper output, using void pointer to store and read dynamically allocated array.
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
There is an error in the code you provided. The error is in the line where you use the "scanf" function inside the first for loop:
scanf("%d", ((int *)arr)[i]);
The issue is with the argument you're passing to scanf. The scanf function expects the address of the variable where it should store the input value, using the & operator. However, in your code, you're not providing the address correctly.
To fix the error, you need to pass the address of the array element to scanf. You can do this by using the & operator before ((int *)arr)[i]. The corrected line should be:
scanf("%d", &((int *)arr)[i]);
There is an error in the code you provided. The error is in the line where you use the "scanf" function inside the first for loop:
scanf("%d", ((int *)arr)[i]);
The issue is with the argument you're passing to scanf. The scanf function expects the address of the variable where it should store the input value, using the & operator. However, in your code, you're not providing the address correctly.
To fix the error, you need to pass the address of the array element to scanf. You can do this by using the & operator before ((int *)arr)[i]. The corrected line should be:
scanf("%d", &((int *)arr)[i]);
I hope this work!
Happy coding!
Thanks. Request to tell error in my earlier code, that fails by giving: 'Segmentation Fault', after accepting input numbers. It is also stated below.
My main concern is that, am unable to find the reason for segmentation fault; inspite of trying hard to figure the same.
Code:
#include <stdio.h>
#include<stdlib.h>
//int partition(void **, int, int *, int, int , int);
int partition(void ** ar, int(* cmp)(const void*, const void*), int left, int right, int pivotIndex);
int cmp(const void *, const void*);
//void do_qsort(void **, int *(const void *, const void*), int, int);
void do_qsort(void **ar, int(*cmp)(const void *, const void *), int left, int right);
int selectPivotIndex(int, int);
int main(){
void ** vals;//array of pointers
int total_elements, *intvals;
printf("How many elements--in the array: : ");
scanf("%d", &total_elements);
vals = malloc(total_elements*sizeof(int));
intvals = malloc(total_elements*sizeof(int));
for(int i=0; i<total_elements; i++) scanf("%d", &intvals[i]);
vals = malloc(total_elements*sizeof(int *));
for(int i=0; i<total_elements; i++) *(int *)vals[i]= &intvals[i]; //*vals[i] = &intvals[i];
do_qsort(vals, cmp, 0, total_elements-1);
for(int i=0; i<total_elements; i++) printf("%d\n", *(int *)vals[i]);
/*for(int i=0; i<total_elements; i++) scanf("%d", (int *)vals+i);
//for(int **p=(int **)vals, **end = p+total_elements; **p<total_elements; p++)
for(int **p=(int **)vals; **p<total_elements; p++)
scanf("%d", *p);
do_qsort(vals, cmp, 0, total_elements-1);
printf("correct");
for(int i =0; i<total_elements; i++)
printf("Element #%d, is: %d", i, vals[i]);
return 1;*/
}
void do_qsort(void **ar, int(*cmp)(const void *, const void *), int left, int right){
int pivotIndex;
printf("q_sort");
printf("entered do_qsort\n with left element index: %d, left element:%d, right element index: %d", left, (int *)(*ar+left), (int *)(*ar +right));// (int *)(*ar)[left], (int *)(*ar)[right]);
if (right<= left) return;
pivotIndex = selectPivotIndex(left, right);
pivotIndex = partition(ar, cmp, left, right, pivotIndex);
do_qsort(ar, cmp, left, pivotIndex-1); do_qsort(ar, cmp, pivotIndex+1, right);
}
int partition(void ** ar, int(* cmp)(const void*, const void*), int left, int right, int pivotIndex){
int idx, store; void *pivot = ar[pivotIndex]; void *tmp = ar[right];
ar[right] = ar[pivotIndex]; ar[pivotIndex]= tmp;
store = left;
for(idx= left; idx<right;idx++){
if(cmp(ar[idx], pivot) <=0){
tmp = ar[idx]; ar[idx]=ar[store]; ar[store]=tmp; store++;
}
}
tmp= ar[right]; ar[right] = ar[store]; ar[store] = tmp;
return store;
}
int cmp(const void * a, const void *b)
{
if ((int*)a<=(int*)b) return 0;
else return 1;
}
int selectPivotIndex(int left, int right)
{
int median;
median = (left+right)/2;
if(median %2==0) median = median +1;
return median;
}
Segmentation fault:
Code:
$ ./quicksort
How many elements--in the array: : 5
10
5
23
8
29
Segmentation fault (core dumped)
request vetting of the reason why "scanf("%d", ((int *)arr+i));" works, when "scanf("%d", ((int *)arr)[i]);" fails.
As mentioned by others:
the square brackets array\[\] automatically dereferences the array's contents, whereas array + i does not.
So the with the [] you get back an int
Code:
#include <stdio.h>
int main(void)
{
int array[] = { 0,1,2,3,4,5};
printf("%d\n", array[3]);
printf("%d\n", *(array +3));
return 0;
}
Last edited by bigearsbilly; 07-19-2023 at 04:16 AM.
Your program is not unsalvable; please make an effort to understand the changes.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void do_qsort(void **ar, int(*cmp)(const void *, const void *), int left, int right);
static int cmp(const void *pa, const void *pb)
{
int a= *(int *)pa;
int b= *(int *)pb;
if (a<b) return -1;
else if (a==b) return 0;
else return 1;
}
int main(){
int *intvals = NULL; //array of integers
int **vals= NULL;//array of pointers
int total_elements;
if (isatty(fileno(stdin))) {
printf("How many elements in the array");
}
scanf("%d", &total_elements);
intvals = malloc(total_elements*sizeof(int));
vals = malloc(total_elements*sizeof(int *));
for(int i= 0; i<total_elements; ++i) {
vals[i]= &intvals[i];
scanf("%d", vals[i]);
}
printf("unsorted:");
for (int i=0; i<total_elements; ++i) {
printf(" %d", *vals[i]);
}
fputc('\n', stdout);
do_qsort((void **)vals, cmp, 0, total_elements-1);
printf("sorted:");
for (int i=0; i<total_elements; ++i) {
printf(" %d", *vals[i]);
}
fputc('\n', stdout);
free(vals);
free(intvals);
return 0;
}
int partition(void ** ar, int(* cmp)(const void*, const void*), int left, int right, int pivotIndex);
static void swap(void **arr, int i, int j) {
void *tmp= arr[i];
arr[i]= arr[j];
arr[j]= tmp;
}
void do_qsort(void **ar, int(*cmp)(const void *, const void *), int left, int right){
int pivotIndex;
if (right<= left) return;
else if (left+1==right) {
if (cmp(ar[left], ar[right])>0) {
swap(ar, left, right);
}
return;
}
pivotIndex = (left+right+1)/2;
pivotIndex = partition(ar, cmp, left, right, pivotIndex);
do_qsort(ar, cmp, left, pivotIndex-1);
do_qsort(ar, cmp, pivotIndex+1, right);
}
int partition(void ** ar, int(* cmp)(const void*, const void*), int left, int right, int pivotIndex){
int idx, store; void *pivot = ar[pivotIndex]; void *tmp = ar[right];
ar[right] = ar[pivotIndex]; ar[pivotIndex]= tmp;
store = left;
for(idx= left; idx<right;idx++){
if(cmp(ar[idx], pivot) <=0){
tmp = ar[idx]; ar[idx]=ar[store]; ar[store]=tmp; store++;
}
}
tmp= ar[right]; ar[right] = ar[store]; ar[store] = tmp;
return store;
}
Compiled on onlinegdb.com.
On sample data of 10 values, in input; as: 15, 1, 30, 2, 70, 3, 65, 3, 4, 91
wanted to see the actual execution, by modifying the code as shown below:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void do_qsort(void **ar, int(*cmp)(const void *, const void *), int left, int right, int counter);
static int cmp(const void *pa, const void *pb)
{
int a= *(int *)pa;
int b= *(int *)pb;
if (a<b) return -1;
else if (a==b) return 0;
else return 1;
}
int main(){
int *intvals = NULL; //array of integers
int **vals= NULL;//array of pointers
int total_elements;
if (isatty(fileno(stdin))) {
printf("How many elements in the array: ");
}
scanf("%d", &total_elements);
intvals = malloc(total_elements*sizeof(int));
vals = malloc(total_elements*sizeof(int *));
for(int i= 0; i<total_elements; ++i) {
vals[i]= &intvals[i];
scanf("%d", vals[i]);
}
printf("unsorted:");
for (int i=0; i<total_elements; ++i) {
printf(" %d", *vals[i]);
}
fputc('\n', stdout);
do_qsort((void **)vals, cmp, 0, total_elements-1, 0);
printf("sorted:");
for (int i=0; i<total_elements; ++i) {
printf(" %d", *vals[i]);
}
fputc('\n', stdout);
free(vals);
free(intvals);
return 0;
}
int partition(void ** ar, int(* cmp)(const void*, const void*), int left, int right, int pivotIndex);
static void swap(void **arr, int i, int j) {
void *tmp= arr[i];
arr[i]= arr[j];
arr[j]= tmp;
}
void do_qsort(void **ar, int(*cmp)(const void *, const void *), int left, int right, int counter){
int pivotIndex;
printf ("\n ============ do_qsort() counter : %d, left: %d, right: %d\n", counter, left, right);
if (right<= left) return;
else if (left+1==right) {
if (cmp(ar[left], ar[right])>0) {
swap(ar, left, right);
}
return;
}
pivotIndex = (left+right+1)/2;
pivotIndex = partition(ar, cmp, left, right, pivotIndex);
printf("\n counter: %d", counter);
do_qsort(ar, cmp, left, pivotIndex-1, counter+1);
do_qsort(ar, cmp, pivotIndex+1, right, counter+1);
}
int partition(void ** ar, int(* cmp)(const void*, const void*), int left, int right, int pivotIndex){
int idx, store;
int current_elements = right - left +1;
void *pivot = ar[pivotIndex]; void *tmp = ar[right];
ar[right] = ar[pivotIndex]; ar[pivotIndex]= tmp;
store = left;
printf("partition: current: left: %d, right: %d, current_elements: %d::", left, right, current_elements);
for (int i=0; i<current_elements; ++i)
printf(" %d", (int *)ar[i]); //Unable to get any meaningful output of it, as shown below
for(idx= left; idx<right;idx++){
if(cmp(ar[idx], pivot) <=0){ printf("\n idx: %d, store: %d, left: %d, right: %d", idx, store, left, right);
tmp = ar[idx]; ar[idx]=ar[store]; ar[store]=tmp; store++;
}
}
tmp= ar[right]; ar[right] = ar[store]; ar[store] = tmp;
return store;
}
Q.1. Have confusion as what is the output implied by the line #84, 85; i.e.
Code:
for (int i=0; i<current_elements; ++i)
printf(" %d", (int *)ar[i]);
as that gives output as shown below. Say, on the first iteration, it gives the output as: -1508742464 -1508742460 -1508742456 -1508742452 -1508742448 -1508742428 -1508742440 -1508742436 -1508742432 -1508742444;
which though are the set of 10 values in the array for each of the 10 iterations, but cannot link to the actual elements in the array.
The reason it worked, must be that need to both type-cast the contents of array (being a pointer to a pointer to an integer), and the fact that ar[i] = *(ar+i); hence *ar[i] = **(ar +i).
But, that means that (int *)*ar[i] should work too.
But, that gives error:
Code:
main.c: In function ‘partition’:
main.c:85:42: warning: dereferencing ‘void *’ pointer
85 | printf(" %d", (int *)*ar[i]);
| ^~~~~~
main.c:85:35: error: invalid use of void expression
85 | printf(" %d", (int *)*ar[i]);
| ^
The reason it worked, must be that need to both type-cast the contents of array (being a pointer to a pointer to an integer), and the fact that ar[i] = *(ar+i); hence *ar[i] = **(ar +i).
But, that means that (int *)*ar[i] should work too...
You state that as if it were fact, but clearly it is not.
The error message is very precise, trust it.
This works because the pointer to void pointer is typecast before being dereferenced...
Code:
printf(" %d", *(int *)ar[i]);
This produces the error because the pointer to void pointer is first being dereferenced, then its value is being typecast...
Code:
printf(" %d", (int *)*ar[i]);
And the error tells you exactly that, and exactly where...
you ought to use printf "%p" for pointers, instead of %d (but you can try %x too, if you wish).
The pointer itself is the location (address) of the variable in the memory, therefore it is actually an integer (or long).
see for example here: https://www.man7.org/linux/man-pages/man3/printf.3.html
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.