I've done this code to read an array, it works properly in the small tests (3x3), however i need it to read a 15x15 one. After 150 scans it has stopped working, returned 3221225477 and closed.
What is happening? How to fix it?
int ** ler(){
FILE *a;
a = fopen("matriz.txt", "r");
int **N;
int b, c, d;
N = malloc(15 * sizeof(int));
for (b = 0; b < 15; b++){
N[b] = malloc(15 * sizeof(int));
}
for (b = 0; b < 15; b++){
for (c = 0; c < 15; c++){
fscanf(a, "%i", &d);
N[b][c] = d;
}
}
return N;
}
At least this problem:
Wrong size allocation
int **N; // vvvvvvvvvvv This is the size of an int
//N = malloc(15 * sizeof(int));
N = malloc(15 * sizeof *N);
// ^^^^^^^^^ The size of a pointer is needed here
With OP's code, when the size of an int < size of an int *, the allocation is undersized.
Avoid that mistake and code with *N rather than attempting to match the type.
// Nice idiom
ptr = malloc(sizeof *ptr * n);
// ^^^^^^^^^^^ The right size regardless of what `ptr` pointers to.
Call fclose(a) when done reading.
Related
I have the task to write a program in C. The program should be able to check for parameters and create arrays that are as big as the parameter I gave. I have to fill the array with random numbers. Works fine so far. Later on my task is to sort the array using pointers. First thing is I did not quite understand how pointers work but I made the sorting work so far. The only problem is, that I can only sort to a size of 4. If my parameter is bigger than 4 I get the first 4 numbers sorted and then a Segmentation fault. I cannot find the issue but the fun part is, that if I add a printf just to print my parameter again it works fine for any parameter I want! I do not know what is happening!
Here is the exact task again, because I think I didn't describe it that well:
To do this, create a dynamic pointer field of the same size and initialize it with pointers to the elements of the int field. When sorting, the pointers should now be sorted so that the first pointer points to the smallest int value, the second to the next largest value, and so on.
int main(int argc, char *argv[]) {
int *array;
int **arrpointer;
int size = atoi(argv[1]);
if (size == 0) {
fprintf(stderr, "Wrong parameter!\n");
return EXIT_FAILURE;
}
//printf("Array-Size : "); //First I had it with scanf, which works perfectly fine without a print
//scanf("%d", &size);
printf("Input%d", size); //This is the print I need somehow!
// allocate memory
array = (int *)malloc(size * sizeof(int)); // Init Array
arrpointer = (int **)malloc(size * sizeof(int)); // Init Pointer Array
//Check Pointer array
if (arrpointer != NULL) {
printf("Memory allocated\n\n");
} else {
fprintf(stderr, "\nNo free memory.\n");
return EXIT_FAILURE;
}
if (array != NULL) {
printf("Memory is allocated\n\n");
//Fill Array
for (int i = 0; i < size; i++) {
array[i] = rand() % 1000; //I know it is not random right now, will add later
int *temp = &array[i];
arrpointer[i] = temp; //Pointer fill
}
} else {
fprintf(stderr, "\nNo free memory to allocate.\n");
return EXIT_FAILURE;
}
shakersort(arrpointer, size); //Function to sort pointers
zeigeFeld(arrpointer, size); //Function to Print
free(array);
free(arrpointer);
return EXIT_SUCCESS;
}
I know its a bit confusing, I am sorry.
I will also add the code where I sort it below.
void swap(int **a, int **b) {
int ram;
ram = **a;
**a = **b;
**b = ram;
}
void shakersort(int **a, int n) {
int p, i;
for (p = 1; p <= n / 2; p++) {
for (i = p - 1; i < n - p; i++)
if (*a[i] > *a[i+1]) {
swap(&a[i], &a[i + 1]);
}
for (i = n - p - 1; i >= p; i--)
if (*a[i] < *a[i-1]) {
swap(&a[i], &a[i - 1]);
}
}
}
This is the code I tried to build for the pointers and it works fine so far.
I hope someone can help or give some input to why my print fixes the problem. I really dont understand!
Thank you for your time and help, let me know if I should add anything!
The program has undefined behavior because the allocation size is incorrect for the array:
arrpointer = (int **)malloc(size * sizeof(int));
allocates space for size integers, but it should allocate space for size pointers to int, which on 64-bit systems are larger than int. Use this instead:
arrpointer = (int **)malloc(size * sizeof(int *));
Or use the type of the destination pointer:
arrpointer = malloc(sizeof(*arrpointer) * size);
This latter syntax is much safer as it works for any non void pointer type.
Note however that this array of pointers is overkill for your purpose. You should just implement the sorting functions on arrays of int:
void swap(int *a, int *b) {
int ram = *a;
*a = *b;
*b = ram;
}
void shakersort(int *a, int n) {
int p, i;
for (p = 1; p <= n / 2; p++) {
for (i = p - 1; i < n - p; i++) {
if (a[i] > a[i + 1]) {
swap(&a[i], &a[i + 1]);
}
}
for (i = n - p - 1; i >= p; i--) {
if (a[i] < a[i - 1]) {
swap(&a[i], &a[i - 1]);
}
}
}
}
Whether the above code actually sorts the array is unclear to me, I never use shakersort.
why do you use pointers before printf??
first you need to know what the pointer is:
the pointer is some kind of variable that contains address of some another variable.
for example:
int b = 2;
int * a = &b;
a variable include the address of variable b. then if you print ((a)) it will give you hex number which is the address of b. if you print ((*a)), compiler will print what in the address that int the variable a and print the amount of number in address of cell b(that means 2).
now i guess you understand what the pointer is, look again at your code and correct the mistakes.
I updated my code from
arrpointer = (int **) malloc(size * sizeof(int));
to
arrpointer = malloc(sizeof *arrpointer * size);
And it works fine!
Thank you all for your help!
The dynamicRandomMatrix function should return a pointer to an array of n pointers each of which points to an array of n random integers.
I got it to print mostly correct, except the first number in the array. This is the output:
n=3: -2084546528, 59, 45
Can anyone help me figure out why the first number in the array is so small? I think it must be something to do with local variables and access or something, but I am not sure.
int** dynamicRandomMatrix(int n){
int **ptr;
ptr = malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) {
int *address = randomArray(n);
ptr[i] = address;
}
return ptr;
free (ptr);
}
int* randomArray(int n){
int *arr;
arr = malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) {
int num = (rand() % (100 - 1 + 1)) + 1;
arr[i] = num;
}
return arr;
free(arr);
}
int main(){
int **ptr;
int i;
ptr = dynamicRandomMatrix(3);
printf("n=3: ");
for (i = 0; i < 3; i++) {
printf("%d, ", *ptr[i]);
}
return 0;
}
In your code,
ptr = malloc(sizeof(int) * n);
is not correct, each element in ptr array is expected to point to a int *, so it should be ptr = malloc(sizeof(int*) * n);. To avoid this, you can use the form:
ptr = malloc(sizeof(*ptr) * n);
That said, all your free(array); and free (ptr); are dead code, as upon encountering an unconditional return statement, code flow (execution) returns to the caller, and no further execution in that block (function) takes place. Your compiler should have warned about this issue. If not, use proper flags to enbale all warnings in your compiler settings.
If I have int **array and want to place a series of numbers in it (I don't know its size), 5 3 4 0 or 9 1 5 8 3 0 as an example. As far as I know I should be using malloc
So I did something like this
int **array;
int n = 1, inp = 0;
while(n){ // scan till the input is 0
scanf("%d", &n);
array = (int**)malloc(sizeof(int*)*(inp+1)); //since inp start at 0
array[inp] = &n; //is this even correct?
inp++;
}
My first question is: Will this method (the loop) upgrade/expand the size of the array or is what I am doing a waste of memory?
The second question is how can I print/edit the values of this array?
EDIT:
From your answers I have came up with the following.
int **array;
int n = 1, inp = 0;
array = (int**)malloc(sizeof(int*));
while(n){
scanf("%d", &n);
realloc( array, sizeof((int*)(inp+1)));
array[inp] = n;
inp++;
}
Is this the correct way to do it?
Note* I am aware that it does not have to be a pointer of a pointer, but I need it to be for something else later on.
You code is wrong for at least these reasons.
1) You keep doing malloc to array and thereby loose previously malloced blocks. The function to use is realloc when extending the size of dynamic memory.
2) You store the address of n instead of the value of n
Besides that it seems strange to use a double pointer. Why not do like:
int *array = NULL;
int n = 1, inp = 0;
while(n){ // scan till the input is 0
scanf("%d", &n);
array = realloc(array, sizeof(int)*(inp+1));
array[inp] = n;
inp++;
}
EDIT after OPs update
If you really want to use a double pointer (i.e. int **array;), you need to allocate memory in two levels.
That could look like:
int **array = malloc(sizeof *array);
*array = NULL;
int n = 1, inp = 0;
while(n){ // scan till the input is 0
scanf("%d", &n);
*array = realloc(*array, sizeof(int)*(inp+1));
(*array)[inp] = n;
inp++;
}
What you're doing in your code is allocating progressively larger areas of memory and saving the input value in the last position of each new area, while losing the pointers to the previously allocated areas. A commom and efficient solution for what you want (which is used in C++'s vectors, I believe) is to allocate some minimum amount of space, then check at each iteration if you are on the verge of exceeding it. In case you are, reallocate the area doubling the space. Something like this:
int i = 0; //iterator
int s = 1; //array size
int n; //input (use do-while so you don't have to worry about initial value)
//it doesn't have to be bidimensional for a single series
int * array = (int *) malloc(sizeof(int) * s);
do
{
if(i == s)
{
s *= 2;
array = (int *) realloc(array, sizeof(int) * s);
}
scanf("%d", &n);
array[i++] = n; //assign with the value, not with the address
}
while(n)
UPDATE: if you really need to use **int, do it like this:
int n, i = 0, s = 1;
int ** array = (int **) malloc(sizeof(int*) * s);
do
{
if(i == s)
{
s *= 2;
array = (int **) realloc(array, sizeof(int *) * s);
}
scanf("%d", &n);
array[i] = (int *) malloc(sizeof(int));
array[i][0] = n;
++i;
}
while(n)
this is quite basic but I've been trying to solve it for a few hours now with no success. This code is supposed to read 3 ints from user input and then, points according to the ints (n = how many, d = dimension, k is unrelated to this part) and create an array of them. For some reason it crashes on the second loop, where it fails to create the second point, but im not sure why. I think it might has something to do with malloc but I'm totally lost, would appreciate any help.
I inserted the input :
5 3 2
1.2 3.4 0.1
2 times before it crashed.
Code is below:
int main(){
double* pdata;
int n,d,k;
scanf("%d %d %d",&n,&d,&k );
SPPoint* parr [n];
for(int i=0; i<n; i++)
{
double darr [d];
for(int j = 0; j < d-1; j++)
{
scanf(" %lf", &darr[j]);
}
scanf(" %lf", &darr[d-1]);
pdata = darr;
parr[i] = spPointCreate(pdata, d, i);
}
}
This is the code for the spPointCreate function:
struct sp_point_t{
double* data;
int dim;
int index;
};
SPPoint* spPointCreate(double* data, int dim, int index){
SPPoint* point = malloc(sizeof(SPPoint*));
if(point == NULL)
{
return NULL;
}
point->data = (double*) malloc(sizeof(data));
for( int i=0 ; i<dim ; i++)
{
point->data[i] = data[i];
}
point->dim = dim;
point->index = index;
return point;
}
SPPoint* point = malloc(sizeof(SPPoint*));
should be: struct SPPoint* point = malloc(sizeof(*point));
point->data = (double*) malloc(sizeof(data));
should be point->data = malloc(dim * sizeof(*point->data));
since you want to allocate dim doubles for your point.
Code is mis-allocating in 2 places
// Bad
SPPoint* spPointCreate(double* data, int dim, int index){
SPPoint* point = malloc(sizeof(SPPoint*)); // allocate the size of a pointer
...
point->data = (double*) malloc(sizeof(data)); // allocate the size of a pointer
Instead avoid mis-coding the type and allocate to the the size of the de-referenced variable.
Also need to allocate N objects.
SPPoint* spPointCreate(double* data, int dim, int index){
size_t N = 1;
SPPoint* point = malloc(sizeof *point * N);// allocate the size of `*point` * N
...
assert(dim >= 0);
N = dim;
point->data = malloc(sizeof *(point->data) * N);
BTW, casting the result of malloc() not needed.
2nd allocation would benefit with a NULL check. More complicated as dim may be 0 and a malloc() return of NULL in that case is OK.
N = dim;
point->data = malloc(sizeof *(point->data) * N);
if (point->data == NULL && N > 0) {
free(point);
return NULL;
}
I have to assign memory to a 3D array using a triple pointer.
#include <stdio.h>
int main()
{
int m=10,n=20,p=30;
char ***z;
z = (char***) malloc(sizeof(char**)*m*n*p);
return 0;
}
Is this correct way of doing this?(I think what i am doing is incorrect.)
To completely allocate a 3D dynamic array you need to do something like the following:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int m=10,n=20,p=30;
char ***z;
z = malloc(m * sizeof(char **));
assert(z != NULL);
for (i = 0; i < m; ++i)
{
z[i] = malloc(n * sizeof(char *));
assert(z[i] != NULL);
for (j = 0; j < n; ++j)
{
z[i][j] = malloc(p);
assert(z[i][j] != NULL);
}
}
return 0;
}
Freeing the data is left as an exercise for the reader.
There's no need to cast the return value of malloc(), in C.
And if you expect to store m * n * p characters directly (and compute the address yourself), then you should of course not scale the allocation by the size of a char **.
You mean:
int m = 10, n = 20, p = 30;
char *z = malloc(m * n * p * sizeof *z);
This will allocate 10 * 20 * 30 = 6000 bytes. This can be viewed as forming a cube of height p, with each "slice" along the vertical axis being n * m bytes.
Since this is for manual addressing, you cannot use e.g. z[k][j][i] to index, instead you must use z[k * n * m + j * m + i].
If you don't need the memory to be allocated in a single, contiguous chunk (which IME is the usual case), you would do something like this:
char ***z;
z = malloc(sizeof *z * m); // allocate m elements of char **
if (z)
{
int i;
for (i = 0; i < m; i++)
{
z[i] = malloc(sizeof *z[i] * n); // for each z[i],
if (z[i]) // allocate n elements char *
{
int j;
for (j = 0; j < n;j++)
{
z[i][j] = malloc(sizeof *z[i][j] * p); // for each z[i][j],
if (z[i][j]) // allocate p elements of char
{
// initialize each of z[i][j][k]
}
}
}
}
}
Note that you will need to free this memory in reverse order:
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
free(z[i][j];
free(z[i]);
}
free(z);
If you really need the memory to be allocated in a contiguous chunk, you have a couple of choices. You could allocate a single block and compute your offsets manually:
char *z = malloc(sizeof *z * m * n * p); // note type of z!
...
z[i * m + j * n + k] = some_value();
When you're done, you just need to do a single free:
free(z);
If you have a C99 compiler or a C11 compiler that supports variable-length arrays, you could do something like this:
int m=..., n=..., p=...;
char (*z)[n][p] = malloc(sizeof *z * m);
This declares z as a pointer to an nxp array of char, and we allocate m such elements. The memory is allocated contiguously and you can use normal 3-d array indexing syntax (z[i][j][k]). Like the above method, you only need a single free call:
free(z);
If you don't have a C99 compiler or a C11 compiler that supports VLAs, you would need to make n, and p compile-time constants, such as
#define n 20
#define p 30
otherwise that last method won't work.
Edit
m doesn't need to be a compile-time constant in this case, just n and p.
You would need the following nested loop -
z = (char**)malloc(sizeof(char*) * m);
for (int i = 0; i < m; ++i)
{
*(z + i) = (char*)malloc(sizeof(char*) * n);
for (int j = 0; j < n; ++j)
{
*(*(z + i)) = (char)malloc(p);
}
}
May not be synactically accurate, but it should be something along these lines.
You want sizeof(char) not sizeof(char**) as the latter will give you the size of a pointer which on most modern systems will be 4 bytes instead of the 1 you're expecting.