#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;
}
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);
I need to implement a matrix_create function that receives a triple pointer.
It compiles well, but when I run it I get the Segmentation Fault error, probably because I messed up somewhere in the memory allocation.
But I cannot find my mistake.
The code
#include <stdio.h>
#include <stdlib.h>
int matrix_create(int ***m, int ze, int sp);
void matrix_init(int **m, int ze, int sp);
int main (void)
{
int ze = 3;
int sp = 3;
int i,j;
int ***m = malloc(sizeof(int**));
*m = malloc(ze * sizeof(int*));
matrix_create(m, ze, sp);
matrix_init(*m, ze, sp);
for(i = 0; i < ze; ++i) {
for(j = 0; j < sp; ++j)
printf("%i\n", *m[i][j]);
}
return 0;
}
int matrix_create(int ***m, int ze, int sp)
{
int i, k;
if (!*m)
return 0;
for (i = 0; i < ze; ++i) {
*m[i] = malloc(sp * sizeof(int));
if (!*m[i]) {
for (k = 0; k < i; ++k)
free(*m[k]);
free(*m);
return 0;
}
}
return 1;
}
void matrix_init(int **m, int ze, int sp)
{
int i,j;
for(i = 0; i < ze; ++i) {
for(j = 0; j < sp; ++j)
m[i][j] = rand() % 1000;
}
}
The index operator [] takes precedence over the indirection operator *. See C Operator Precedence.
This means you have to change
*m[i]
to
(*m)[i]
in the function matrix_create:
(*m)[i] = malloc(sp * sizeof(int));
if (!(*m)[i]) {
.....
}
and in the main program:
printf("%i\n", (*m)[i][j]);
I'm working on a project that requires somewhat similar functionality to the program below so I've tried to create a simpler program to debug my larger program. The threads I'm creating are returning values that are inconsistent with their expected output but their return values are not random. It almost seems like the threads are returning the values from other threads or that the variable they are returned to ("tmp") is updating.
The expected output should be...
0 1
1 2
#include <stdio.h>
#include <pthread.h>
struct Numbers {
int x;
int y;
};
void *go(void* param)
{
struct Numbers* nums = (struct Numbers*) param;
int sum = nums -> x + nums -> y;
return (void*) sum;
}
int main()
{
int result[2][2];
int tmp;
pthread_t thread[2][2];
int i, j;
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
struct Numbers nums;
nums.x = i;
nums.y = j;
pthread_create(&thread[i][j], NULL, go, &nums);
}
}
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
pthread_join(thread[i][j], (void*) &tmp);
result[i][j] = tmp;
}
}
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
printf("%d\t", result[i][j]);
}
printf("\n");
}
return 0;
}
You're passing the address of a variable that probably won't exist once the thread begins executing, or at least will be seen by multiple threads, or is a data race as one thread writes it while the others read it.
A general solution is to dynamically allocate both the arguments and results of your thread, and let the caller and thread communicate that way.
Example:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct threadargs {
int x;
int y;
};
struct threadresults {
int sum;
int product;
};
void* threadfunc(void* args_void) {
// Get thread args in usable type.
struct threadargs* args = args_void;
struct threadresults* results = NULL;
//Compute.
int sum = args->x + args->y;
int product = args->x * args->y;
// Return the result.
results = malloc(sizeof(*results));
results->sum = sum;
results->product = product;
free(args);
return results;
}
int main()
{
pthread_t thread[2][2];
struct threadresults* results[2][2] = {0};
int i, j;
for (i = 0;i < 2; ++i) {
for (j = 0; j < 2; ++j) {
struct threadargs* args = malloc(sizeof(*args));
args->x = i;
args->y = j;
pthread_create(&thread[i][j], NULL, threadfunc, args);
}
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
void* result;
pthread_join(thread[i][j], &result);
results[i][j] = result;
}
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
printf("sum: %d\tproduct: %d\n",
results[i][j]->sum, results[i][j]->product);
}
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
free(results[i][j]);
}
}
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).
This code below is the code for finding the determinant for 3x3 matrix (this code is intended for nxn matrix, but for the sample, I used 3x3), using recursive
The result is working fine, but I wonder what errors in this code make this must be the printf("\n") before calling the sub-function (itself) or else it will return the error 0xc0000fd (stack overflow).
#include "stdio.h"
#include "stdlib.h"
#include "conio.h"
#define size 3
void trimarray(int**rrayrc,int**rrayout, int dim,int cuti,int cutj)
{
int i, j;
int ti = 0,tj;
for(i = 0; i<dim; i++)
{
tj = 0;
for(j = 0; j< dim; j++)
{
if(!((i==cuti)||(j==cutj)))
{
rrayout[ti][tj] = rrayrc[i][j];
}
if(j!=cutj) {tj++;}
}
if(i!=cuti) {ti++;}
}
}
void initializearray(int** rray,int dim)
{
int i, j;
for(i = 0; i<dim; i++)
{
for(j = 0; j<dim; j++)
{
rray[i][j] = 0;
}
}
}
int det(int** rray, int dim)
{
int i,j;
int cut[dim-1][dim-1];
int* cutp[i];
int mul = 1,sum=0;
if(dim >1)
{
for(i = 0; i<dim-1; i++)
{
cutp[i] = cut[i];
}
initializearray(cutp,dim-1);
for(i = 0; i<dim; i++)
{
printf("\n",dim); //<< Without this the program won't work
trimarray(rray,cutp,dim,0,i);
sum+=det(cutp,dim-1)*mul*rray[0][i];
mul = 0-mul;
}
return sum;
}
else
{
return rray[0][0];
}
}
int main()
{
int test[size][size] = {2,-3,-2,-6,3,3,-2,-3,-2};
int* testpntr[size];
int i,deter;
for(i = 0; i<size; i++)
{
testpntr[i] = test[i];
}
deter = det(testpntr,size);
printf("[%d]",deter);
getch();
return 0;
}
The answers will be dearly appreciated.
int* cutp[i]; is undefined behavior since i is uninitialized at this stage. You have no idea what is the size of cutp array.