I am trying to access a structure with a pointer to an integer , from main. But the program crashes. It needs to be built with "std=c99" option as it is the requirement in a test.
The code is as follows:
#include <stdio.h>
#include <malloc.h>
struct Results{
int *A;
int N;
};
struct Results solution(int A[], int N, int K) {
struct Results result;
// write your code in C99 (gcc 4.8.2)
int* T = (int*) malloc(N*sizeof(int));
result.A = A;
result.N = N;
int count = 0;
while(count < K)
{
for(int i = 0; i < N; i++)
{
if(i > 0)
{
T[i] = A[i-1];
}
else
{
T[0] = A[N-1];
}
}
count++;
for(int i = 0; i < N; i++)
{
A[i] = T[i];
}
};
for(int i = 0;i < N; i++)
{
A[i] = T[i];
}
return result;
}
struct Results solution(int A[], int N, int K);
void main()
{
int B[5] = {3,8,9,7,6};
struct Results st;
solution(B,sizeof(B),1);
}
The trouble is at line:
" solution(B,sizeof(B),1);"
What am I doing wrong?
Please help.
You see sizeof(B) would give the number of elements in B times the size of an int, use sizeof(B) / sizeof(B[0]) instead.
Related
I have a problem returning dynamic array pointer with function parameter. I get segfault
#include <stdio.h>
#include <stdlib.h>
void createArray(int *ptr, int n)
{
ptr = malloc(n * sizeof(int));
for(int i = 1; i <= n; ++i)
{
*(ptr + (i - 1)) = i*i;
}
}
int main() {
int *array = NULL;
int n = 5;
createArray(array, n);
for(int i = 0; i < n; ++i)
{
printf("%d", array[i]);
}
return 0;
}
I have to fill my array with i*i, when I is from 1 to n.
I don't get any errors or warnings. Just message about segmentation fault. Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
Memory must be allocate in the calling function, but not in called.
This variant works:
#include <stdio.h>
#include <stdlib.h>
void createArray(int *ptr, int n){
int i;
for(i = 1; i <= n; i++) {
*(ptr + (i - 1)) = i*i;
// fprintf(stdout,"%d %d\n", i, *(ptr + (i -1)));fflush(stdout);
}
}
int main() {
int i, n, *array = NULL;
void *pvc;
n = 5;
array = (int *)malloc(n * sizeof(int));
createArray(array, n);
for(i = 0; i < n; i++) {
fprintf(stdout,"%d %d\n", i, array[i]);fflush(stdout);
}
pvc = (void *)array;
free(pvc);
return 0;
}
You can change pointer through function parameters like this:
void createArray(int **ptr, int n)
{
*ptr = malloc(n * sizeof(int));
for(int i = 1; i <= n; ++i)
{
(*ptr)[i - 1] = i*i;
}
}
int main() {
int *array = NULL;
int n = 5;
createArray(&array, n);
Remember to call function like this: createArray(&array, n);
This question doesn't require any initial explanation, other that to show the examples.
Why does this work (prints the contents of array a):
#include <stdio.h>
int a[100];
void check(int **b)
{
int i;
for (i = 0; i < 100; i++)
printf("%d ", b[0][i]);
}
int main()
{
int *arr = a;
int i;
for (i = 0; i < 100; i++)
{
a[i] = i;
}
check(&arr);
return 0;
}
and this doesn't (compiles with onlinegdb c compiler, but prints nothing)?
#include <stdio.h>
int a[100];
void check(int **c)
{
int i;
for (i = 0; i < 100; i++)
printf("%d ", c[0][i]);
}
int main()
{
int i;
for (i = 0; i < 100; i++)
{
a[i] = i;
}
check((int**)&a);
return 0;
}
I understand that array is a special data type in C, but shouldn't casting it to a pointer type or assigning it to one be the same? Is there a way to make the second example work without the additional pointer?
I have been solving a problem of CyclicRotation. This is my code:
#include<stdio.h>
#include<stdlib.h>
struct Results{
int *A;
int N;
};
struct Results solution(int A[], int N, int K){
struct Results result;
int *tab, i=0, j=0;
tab = (int*) malloc(N*sizeof(int));
if(N==0){
result.A = A;
result.N = N;
return result;
}
if(K>N){
K = K % N;
}
if(K<N && N != 0){
for(i=N-K;i<N;i++){
tab[j] = A[i];
j = j + 1;
}
i = 0;
while(i<N-K){
tab[j] = A[i];
i++;
j++;
}
} else {
tab = A;
}
result.A = tab;
result.N = N;
return result;
}
int main()
{
int j[]={2,3,4,5,6,7,8};
int mylen;
int myk = 3;
mylen = sizeof(j)/sizeof(j[0]);
return 0;
}
I tried this in the code:
int main()
{
int j[]={2,3,4,5,6,7,8};
int mylen;
int myk = 3;
mylen = sizeof(j)/sizeof(j[0]);
printf("The result is %d",solution(j,mylen,myk).A);
return 0;
}
The expected result is 6782345, but the result in the console is different:
The result is -591373584
I'm not sure if the array printing is correct (given that is an array, perhaps I need a loop?). Please, could you give me a help? Thank you in advance.
int main()
{
int j[]={2,3,4,5,6,7,8};
int mylen;
int myk = 3;
mylen = sizeof(j)/sizeof(j[0]);
struct Results results = solution(j, mylen, myk);
for(int i = 0; i < mylen; i++)
printf("%d\n", results.A[i]);
free(results.A);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int *squares(int max_val) {
int *result = malloc(max_val * sizeof(int));
int i;
for(i = 1; i <= max_val; i++) {
result[i-1] = i*i;
}
return(result);
}
int main() {
int *sq = squares(10);
int i;
for(i = 0; i < 10; i++) {
printf("%d\t", sq[i]);
}
printf("\n");
return(0);
}
Basically take's an integer and returns a integer array of its squares. (Above works)
How would I do this without malloc or pointers?
#include <stdio.h>
#include <stdlib.h>
int[] squares(int max_val) {
int result[max_val];
int i;
for(i = 1; i <= max_val; i++) {
result[i-1] = i*i;
}
return(result);
}
int main() {
int sq[] = squares(10);
int i;
for(i = 0; i < 10; i++) {
printf("%d\t", sq[i]);
}
printf("\n");
return(0);
}
Above errors because of the function call. Is this possible? Or do we have to do it with pointers?
How about something like this.. ?
#include <stdio.h>
#include <stdlib.h>
void squares(int values[], int max_val) {
for(int i = 1; i <= max_val; i++) {
values[i - 1] = i * i;
}
}
int main() {
int sq[10];
squares(sq, 10);
int i;
for(i = 0; i < 10; i++) {
printf("%d\t", sq[i]);
}
printf("\n");
return(0);
}
This
int[] squares(int max_val) {
int result[max_val];
int i;
for(i = 1; i <= max_val; i++) {
result[i-1] = i*i;
}
return(result);
}
is not valid C:
a.c:3:4: error: expected identifier or ‘(’ before ‘[’ token
int[] squares(int max_val)
It should be
int *squares(int max_val) {
...
}
Putting that aside, your second squares returns a pointer to a local array.
This array ceases to exist once squares ends it's execution, so you are
returning an pointer that become invalid the moment it returns.
Also
int sq[] = squares(10);
is invalid C as well
a.c:9:13: error: invalid initializer
int sq[] = squares(10);
^~~~~~~
you cannot assign a function value to an array. The correct
version is
int *sq = squares(10);
So, if you don't want squares to allocate memory with malloc for the result, then you can
either allocate the memory in main or create an array in main and pass it to
squares:
int squares(int *result, int max_val) {
if(result == NULL || max_val <= 0)
return 0;
int i;
for(i = 1; i <= max_val; i++) {
result[i-1] = i*i;
}
return 1;
}
// version 1
int main() {
int *sq = malloc(10 * sizeof *sq);
// NEVER forget to check the return value of malloc
if(sq == NULL)
{
fprintf(stderr, "not enough memory\n");
return 1;
}
squares(sq, 10);
int i;
for(i = 0; i < 10; i++) {
printf("%d\t", sq[i]);
}
printf("\n");
free(sq); // NEVER forget to free
return 0;
}
// version 2
int main() {
int sq[10];
squares(sq, sizeof sq / sizeof sq[0]);
int i;
for(i = 0; i < 10; i++) {
printf("%d\t", sq[i]);
}
printf("\n");
return 0;
}
I have a pointer to a pointer ("paths") and I want to reallocate each pointer (each "path"). But I get a crash. Generally I am trying to find all possible powers of a number, which one can compute for some amount of operations (e.g for two operations we can get power of three and four (one operation for square of a number, then another one either for power of three or four)). I figured out how to do it on paper, now I am trying to implement it in code. Here is my try:
#include <stdio.h>
#include <stdlib.h>
void print_path(const int *path, int path_length);
int main(void)
{
fputs("Enter number of operations? ", stdout);
int operations;
scanf("%i", &operations);
int **paths, *path, npaths, npath;
npaths = npath = 2;
path = (int*)malloc(npath * sizeof(int));
paths = (int**)malloc(npaths * sizeof(path));
int i;
for (i = 0; i < npaths; ++i) // paths initialization
{
int j;
for (j = 0; j < npath; ++j)
paths[i][j] = j+1;
}
for (i = 0; i < npaths; ++i) // prints the paths, all of them are displayed correctly
print_path(paths[i], npath);
for (i = 1; i < operations; ++i)
{
int j;
for (j = 0; j < npaths; ++j) // here I am trying to do it
{
puts("trying to reallocate");
int *ptemp = (int*)realloc(paths[j], (npath + 1) * sizeof(int));
puts("reallocated"); // tried to write paths[j] = (int*)realloc...
paths[j] = ptemp; // then tried to make it with temp pointer
}
puts("memory reallocated");
++npath;
npaths *= npath; // not sure about the end of the loop
paths = (int**)realloc(paths, npaths * sizeof(path));
for (j = 0; j < npaths; ++j)
paths[j][npath-1] = paths[j][npath-2] + paths[j][j];
for (j = 0; j < npaths; ++j)
print_path(paths[j], npath);
puts("\n");
}
int c;
puts("Enter e to continue");
while ((c = getchar()) != 'e');
return 0;
}
void print_path(const int *p, int pl)
{
int i;
for (i = 0; i < pl; ++i)
printf(" A^%i -> ", p[i]);
puts(" over");
}
I am not sure the problem resides with the call to realloc(), rather you are attempting to write to locations for which you have not created space...
Although you create memory for the pointers, no space is created (allocate memory) for the actual storage locations.
Here is an example of a function to allocate memory for a 2D array of int:
int ** Create2D(int **arr, int cols, int rows)
{
int space = cols*rows;
int y;
arr = calloc(space, sizeof(int));
for(y=0;y<cols;y++)
{
arr[y] = calloc(rows, sizeof(int));
}
return arr;
}
void free2DInt(int **arr, int cols)
{
int i;
for(i=0;i<cols; i++)
if(arr[i]) free(arr[i]);
free(arr);
}
Use example:
#include <ansi_c.h>
int main(void)
{
int **array=0, i, j;
array = Create2D(array, 5, 4);
for(i=0;i<5;i++)
for(j=0;j<4;j++)
array[i][j]=i*j; //example values for illustration
free2DInt(array, 5);
return 0;
}
Another point here is that it is rarely a good idea to cast the return of [m][c][re]alloc() functions
EDIT
This illustration shows my run of your code, just as you have presented it:
At the time of error, i==0 & j==0. The pointer at location paths[0][0] is uninitialized.
EDIT 2
To reallocate a 2 dimension array of int, you could use something like:
int ** Realloc2D(int **arr, int cols, int rows)
{
int space = cols*rows;
int y;
arr = realloc(arr, space*sizeof(int));
for(y=0;y<cols;y++)
{
arr[y] = calloc(rows, sizeof(int));
}
return arr;
}
And here is a test function demonstrating how it works:
#include <stdio.h>
#include <stdlib.h>
int ** Create2D(int **arr, int cols, int rows);
void free2DInt(int **arr, int cols);
int ** Realloc2D(int **arr, int cols, int rows);
int main(void)
{
int **paths = {0};
int i, j;
int col = 5;
int row = 8;
paths = Create2D(paths, col, row);
for(i=0;i<5;i++)
{
for(j=0;j<8;j++)
{
paths[i][j]=i*j;
}
}
j=0;
for(i=0;i<5;i++)
{
for(j=0;j<8;j++)
{
printf("%d ", paths[i][j]);
}
printf("\n");
}
//reallocation:
col = 20;
row = 25;
paths = Realloc2D(paths, col, row);
for(i=0;i<20;i++)
{
for(j=0;j<25;j++)
{
paths[i][j]=i*j;
}
}
j=0;
for(i=0;i<20;i++)
{
for(j=0;j<25;j++)
{
printf("%d ", paths[i][j]);
}
printf("\n");
}
free2DInt(paths, col);
getchar();
return 0;
}
The realloc() does not fail. What fails is that you haven't allocated memory for the new pointers between paths[previous_npaths] and paths[new_npaths-1], before writing to these arrays in the loop for (j = 0; j < npaths; ++j).