I have this code:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
void ft_ultimate_ft(int *********nbr)
{
printf("%d", *********nbr);
}
int main(){
/*Start of problem*/
int *a;
int **b = &a;
int ***c = &b;
int ****d = &c;
int *****e = &d;
int ******f = &e;
int *******g = &f;
int ********h = &g;
int *********i = &h;
/*end of problem*/
*********i = 42;
ft_ultimate_ft(i);
return 0;
}
I need to include pointer-to-pointer declaration in the loop (for example, while). It's needed to decrease number of declarations.
I am assuming that I have properly understood you question, which is to create a multiple pointer to a number using a loop and then assign value to it.
I wrote a piece of code that partly completes your requirement but still need to know how many layers there are after the loop.
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
void ft_ultimate_ft(int *********nbr)
{
printf("%d", *********nbr);
}
int main() {
int t = 10;
int n = 8;
void * p = &t;
for (int i = 0; i < n; i++)
{
void* * s = (void **)malloc(sizeof(void*));
*s = p;
p = s;
}
/*end of problem*/
int *********real = (int *********)p;
*********real = 42;
ft_ultimate_ft(real);
return 0;
}
Which outputs 42
The clean up part of the program is not written
PS. In your code, the pointer a is indeterminate and I do not think that your original code can work properly.
Related
I'm trying to change the x value in this code but I'm getting segmentation fault.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int **x;
} Type;
int main() {
int a = 1;
Type *type = malloc(sizeof(Type));
type->x[0] = &a;
return 0;
}
if you want an array of pointers to ints
int main() {
int a = 1;
Type *type = malloc(sizeof(Type));
type->x = malloc(sizeof(int*) * 10)) ;// say we need 10
type->x[0] = &a;
return 0;
}
I managed to put the value in the pointer while in the function, However when i come back to the main i just dont get the values. Where am i wrong? sending parameters wrong? wrong allocation? Here's the code:
bool wc(int* nlines, int* nwords, int* nchars)
{
int lines=5,chars=6,words=7;
nchars = (int *) malloc(chars*sizeof(int));
*nchars = chars;
nlines = (int *) malloc(lines*sizeof(int));
*nlines = lines;
nwords = (int *) malloc(words*sizeof(int));
*nwords = words;
}
int main() {
int* chars; int* words; int* lines;
int res = wc(&lines,&words,&chars);
printf("%d %d %d\n",chars,lines,words);
return 0;
}
If all you want to do is be able to set 3 int values inside a function then this is how I would so it.
#include <stdio.h>
#include <stdbool.h>
bool wc(int* nlines, int* nwords, int* nchars)
{
int lines=5,chars=6,words=7;
*nchars = chars;
*nlines = lines;
*nwords = words;
return true;
}
int main() {
int lines = 0;
int words = 0;
int chars = 0;
int res = wc(&lines,&words,&chars);
printf("%d %d %d\n",chars,lines,words);
return 0;
}
If for some reason you must use pointers as shown in your example then this will do what you want.
#include <stdio.h>
#include <stdbool.h>
bool wc(int** nlines, int** nwords, int** nchars)
{
int lines=5,chars=6,words=7;
*nchars = malloc(sizeof(int));
**nchars = chars;
*nlines = malloc(sizeof(int));
**nlines = lines;
*nwords = malloc(sizeof(int));
**nwords = words;
return true;
}
int main() {
int* chars; int* words; int* lines;
int res = wc(&lines,&words,&chars);
printf("%d %d %d\n",*chars,*lines,*words);
free(chars);
free(words);
free(lines);
return 0;
}
As you can see this just means you need to add a bunch more * all over the place.
In C function input variables are passed by value, not reference. So when you assign them locally, the value in the caller scope is unaffected. E.g.
void foo(int a) {
a = 5;
}
int main() {
int b = 3;
foo(b);
// here, b is still 3
}
This is exactly what you are doing in your example, though your variables are not int, but int*.
If your input variable is a pointer though, you can change the memory that the variable points to, and this will obviously reflect in the calling scope. E.g.
void foo(int *a) {
*a = 5;
}
int main() {
int b = 3;
foo(&b);
// here, b is 5
}
In your case, you want to allocate pointers, so you want your function signature to be a pointer to a pointer. E.g.
void foo(int **a) {
*a = malloc(sizeof(int));
}
int main() {
int* b = NULL;
foo(&b);
// here, b is allocated to a valid heap area
free(b);
}
so I need to use qsort() to sort an array that contains a structure
#include <stdio.h>
// =========
struct pair
{
int encounters;
};// pair{}
int compaireEncounters(const void*, const void*);
int main()
{
struct pair* working[5];
working[0]->encounters = 10;
working[1]->encounters = 3;
working[2]->encounters = 1;
qsort(working, 5, sizeof(struct pair), compareEncounters);
int i = 0;
while (i < 3)
{
printf("%d \n", working[i]->encounters)
i++;
}
}
int compaireEncounters(const void* av, const void* bv)
{
int a = ((struct pair*)av)->encounters;
int b = ((struct pair*)bc)->encounters;
return(a > b);
}
I am trying to get the output:
1
3
10
but instead i get a segmentation fault core dump.
What is the issue here?
You must assign pointers to valid buffers before dereferencing pointers.
In this case, working should be an array of the structure, not an array of pointers.
Also don't forget to initialize all elements to be sorted.
There are also more mistakes in your code:
qsort is used without including proper header (stdlib.h)
Undeclared compareEncounters is used in the main function.
A semicolon is missing after the printf() statement.
Undeclared bc is used in the compaireEncounters function.
Fixed code:
#include <stdio.h>
#include <stdlib.h>
// =========
struct pair{
int encounters;
};// pair{}
int compaireEncounters(const void* , const void*);
int main() {
struct pair working[5];
working[0].encounters = 10;
working[1].encounters = 3;
working[2].encounters = 1;
working[3].encounters = 334;
working[4].encounters = 42;
qsort(working, 5, sizeof(struct pair), compaireEncounters);
int i = 0;
while (i < 3) {
printf("%d \n", working[i].encounters);
i++;
}
}
int compaireEncounters(const void* av, const void* bv){
int a = ((struct pair*)av)->encounters;
int b = ((struct pair*)bv)->encounters;
return(a > b);
}
If you want to work with an array of pointers,
Allocate buffers and assign them before dereferencing.
Fix the element size for qsort().
Fix compaireEncounters to compare the pointers to the structure.
#include <stdio.h>
#include <stdlib.h>
// =========
struct pair{
int encounters;
};// pair{}
int compaireEncounters(const void* , const void*);
int main() {
struct pair* working[5];
working[0] = malloc(sizeof(*working[0])); working[0]->encounters = 10;
working[1] = malloc(sizeof(*working[1])); working[1]->encounters = 3;
working[2] = malloc(sizeof(*working[2])); working[2]->encounters = 1;
working[3] = malloc(sizeof(*working[3])); working[3]->encounters = 334;
working[4] = malloc(sizeof(*working[4])); working[4]->encounters = 42;
qsort(working, 5, sizeof(*working), compaireEncounters);
int i = 0;
while (i < 3) {
printf("%d \n", working[i]->encounters);
i++;
}
}
int compaireEncounters(const void* av, const void* bv){
int a = (*(struct pair**)av)->encounters;
int b = (*(struct pair**)bv)->encounters;
return(a > b);
}
This simple code crashes (Segmentation fault) and I don't understand why. Seems like this [] operation does not work properly with an array of structures. Maybe somebody knows the reason behind this weird behavior.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 3
typedef struct{
int a;
char * b;
}qwe;
void foo ( qwe **out){
int i;
*out = (qwe*)malloc(SIZE*sizeof(qwe));
for (i=0;i<SIZE;i++){
out[i]->a = i;
out[i]->b = strdup("Hello");
}
}
int main() {
int i = 0;
qwe *p = NULL;
foo(&p);
for (i=0;i<SIZE;i++)
printf("Int: %d, str: %s \n",p[i].a , p[i].b);
}
With the declaration qwe *p = NULL; you are not declaring an array of pointers but of the actual struct.
But in foo you are dereferrencing the arrays content as pointer and that is not correct.
Your approach can be rewritten like this:
for (int i = 0; i<SIZE; i++) {
(*out)[i].a = i;
(*out)[i].b = _strdup("Hello");
}
Another approach that makes the dereferrency better readable (in my opinion) would be to pass a reference to the array:
void foo1(qwe *& out) {
out = (qwe*)malloc(SIZE * sizeof(qwe));
for (int i = 0; i<SIZE; i++) {
out[i].a = i;
out[i].b = _strdup("Hello");
}
}
I know you can return a type of pointer from a function.
ex. void *foo()
Can you return a type of pointer to pointer in a function?
ex. void **foo2()
Here is more info about my question:
I try to assign a ptr-to-ptr, tmp2, to blocks[i][j], and then return tmp2. blocks[i][j] is a ptr-to-ptr as well.
I'm confused to manipulate a ptr to a ptr-to-ptr: I am not sure if return ((tmp2+i)+j); is the cause of the segmentation fault at line printf("2---%d\n", **tmpPtr2);. To debug, I try to print: printf("%d\n", *( (*(tmp2+i)) +j) ); However, it causes a new segmentation fault.
#include <stdio.h>
#include <stdlib.h>
int **blocks, **tmp2;
int n = 10;
int **findBlock2(int b){
int i, j ;
for (i=0; i<n; i++){
for (j=0; j<n; j++){
if (blocks[i][j]==b){
printf("%d\n", blocks[i][j]);
//Segmentation fault
printf("%d\n", *((*(tmp2+i))+j) );
return ((tmp2+i)+j);
}
}
}
return NULL;
}
int main(int argc, const char * argv[]) {
int i, j;
int **tmpPtr2;
//allocate memory space and assign a block to each index
blocks=malloc(n * sizeof *blocks);
for (i=0; i<n; i++) {
blocks[i]=malloc(n * sizeof(*blocks[i]));
blocks[i][0]=i;
}
if ((tmpPtr2=findBlock2(4))==NULL) return -1;
//Segmentation Fault
printf("2---%d\n", **tmpPtr2);
return 0;
}
Update to answer my question:
(1) Adding ttmp2=blocks; to the top of findBlock2() removed both segfaults.
(2) return ((tmp2+i)+j); shows how to manipulate a ptr-to-ptr pointing to a ptr-to-ptr or a 2D array
(3) printf("%d\n", *( (*(tmp2+i)) +j) ); shows how to do (2) and dereference it.
Hope it helps others
Yeah, just like you would with any pointer variables.
#include <stdio.h>
#include <stdlib.h>
int ** function(){
int ** matrix = malloc(sizeof(int*));
*matrix = malloc(sizeof(int));
matrix[0][0] = 5;
return matrix;
}
int main()
{
int **matrix = function();
printf("%d",matrix[0][0]);
free(matrix[0]);
free(matrix);
return 0;
}
Adding to the other part. In your function findBlock2 besides accessing an invalid reference that has already been pointed out, it seems that your objective is to return a reference to the block that fulfills if statement. If that is the case then returning a pointer to int* should suffice.
int *findBlock2( int b )
/////////////////
return ( *(blocks+i)+j );
You probably want a 2D array at not some slow, fragmented lookup table. In that case, do like this:
#include <stdlib.h>
void* alloc_2D (size_t x, size_t y)
{
return malloc (sizeof (int[x][y]));
}
int main (void)
{
const size_t X = 5;
const size_t Y = 3;
int (*arr_2D)[Y] = alloc_2D(X, Y);
// X dimension was omitted in declaration to make array syntax more intuititve:
arr_2D[i][j] = something;
...
free(arr_2D);
}
The answer is "yes". Please refer the following code:
#include <stdio.h>
#include <malloc.h>
void ** foo2(void){
int **p = malloc(sizeof(*p));
return (void**)p;
}
int main(void) {
printf("%p\n", foo2());
return 0;
}
The result is (in my 32-bit platform):
0x80e9008