What should I consider thinking about when understanding the output? Because right now my output is garbage for 20 integers and I dont know why. MY objective is to create 20 arrays with 30 integers in each one. So the final array will have integers of 19 to 48.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
int **p;//Declaration of a pointer variable
int i = 0, j;
int rows = 20;
int columns = 30;
p = (int**)malloc(20 * sizeof(int)); //First "bookend" allocates space
printf("Hello World! I have created a dynamic 20-array of 20x30 integers!\n");
if (p == NULL)
{
printf("Failed to allocated memory!");
exit(1);
}
for (i = 0; i < 20; i++)
{
if (p[i] == NULL)
{
printf("Integers not allocated! ");
}
p[i] = (int**)malloc(20 * sizeof(int));
}
for (i = 0; i < 20; i++)
{
for (j = 0; j < 20; j++)
{
if (p[j] == NULL)
{
printf("Integers not allocated! ");
}
p[i][j] = (int *)malloc(40 * sizeof(int));
}
printf("%d\n", p[(i+1)+j]);
}
free(p);
return 0;
}
I hope I got your question right...
What you are getting isn't exactly garbase... When doing p[i][j] = (int *)malloc(40 * sizeof(int)); you are just allocating one more array with 40 elements and putting it's address in p[i][j]... So when you try to print p[(i+1)+j] you are printing the address of that 40 elements array you malloc'd.
There are several issues with your code:
For the initial allocation, each element is an int *, so you need 20 * sizeof(int *), not 20 * sizeof(int).
Any space allocated by malloc is uninitialized, so attempting to read it is undefined behavior. If on the other hand you use calloc, that initializes the allocated memory to all 0.
You go through an extra set of loops attempting to allocate another array to each int location. If you were trying to create a 3D array (and defined p as int ***) that would work, but not for a 2D array.
Don't cast the return value of malloc, as that can mask subtle bugs.
If you want to dynamically allocate a 20 X 30 array of int, you do it like this:
// first allocate 20 int*
int **p = malloc(20 * sizeof(int *));
if (p == NULL) {
perror("malloc failed");
exit(1);
}
int i;
for (i=0;i<30;i++) {
// for each row, allocate 30 int
p[i] = malloc(30 * sizeof(int));
if (p[i] == NULL) {
perror("malloc failed");
exit(1);
}
}
Note that this doesn't set any values in the 2D array, it just allocates the memory for it.
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!
int* dynamicArray(int n, int queries_rows, int queries_columns, int** queries, int* result_count) {
int i,j;
int lastAnswer = 0,y,resultCount = 0;
int *result = NULL;
int **seqList = (int**) calloc (n,sizeof(int*));
for (i=0; i<queries_rows;i++)
{
y = (queries[i][1] ^ lastAnswer)% n;
if(queries[i][0] == 1){
if(seqList[y]==NULL){
int *dummy = (int*) calloc (2,sizeof(int));
seqList[y]=dummy;
}
for(j=0;j<n;j++){
if(seqList[y][j])
continue;
else {
printf("%d %d entry %d",y,j,seqList[y][j]);
seqList[y][j] = queries[i][2];
}
}
}
if(queries[i][0] == 2){
lastAnswer = seqList[y][queries[i][2]];
resultCount++;
if(result == NULL)
result = (int*) calloc (1,sizeof(int));
else {
result = (int*) realloc (result,resultCount * sizeof(int));
}
result[resultCount - 1] = lastAnswer;
}
}
*result_count = resultCount;
return result;
}
Anything wrong with the above realloc usage for giving out a "segfault"?
Is this the right way to use realloc?
Also running a debugger is not possible as this is a function completion of cooding site?
You are missing a few spots to "derive" a pointer to do any sort of action with the value...so you're probably trying to allocate/reallocate dynamic memory with the integers memory address instead of the value of the pointer(which would be deriving it).
Try putting an asterisk in front of the pointer variables when allocating/reallocating the memory.
Note these lines
int **seqList = (int**) calloc (n,sizeof(int*));
for (i=0; i<queries_rows;i++)
{
y = (queries[i][1] ^ lastAnswer)% n; // <-- ?
if(queries[i][0] == 1) {
if(seqList[y]==NULL) {
int *dummy = (int*) calloc (2, sizeof(int));
// ^^^
seqList[y]=dummy;
// ^^^
}
for( j = 0; j < n; j++ ) {
// ^^^^^ is n bigger than 2?
if( seqList[y][j] )
// ^^^
continue;
else {
// ...
seqList[y][j] = queries[i][2];
// ^^^
}
}
}
According to what the OP commented "n will be till 10^5", but only enough memory to store a couple of ints has been allocated.
Also note that both calloc and realloc may fail, but none of the values returned by those functions are checked.
Further references to address other issues
Do I cast the result of malloc?
calloc with structure with pointers
Proper usage of realloc
I would like to know why the first two elements are always non-zero. I don't know how more I can describe the question, but this is not allowing me to post the question, so I'm writing this. Not sure if this will work.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
void printMatrix(int **m)
{
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++)
printf("%d ", m[i][j]);
printf("\n");
}
}
int main(int argc, char const *argv[])
{
int **matrix;
matrix = (int **) calloc(sizeof(int), SIZE);
for (int i = 0; i < SIZE; ++i)
matrix[i] = (int *) calloc(sizeof(int), SIZE);
printf("%s\n", "Matrix initialized.");
printMatrix(matrix);
return 0;
}
Output:
Matrix initialized.
1371548192 32653 0
0 0 0
0 0 0
You're not allocating enough memory:
matrix = (int **) calloc(sizeof(int), SIZE);
Here you're attempting to create an array of 3 int *, but you're only allocating space for 3 int. If a pointer is larger than an int on your system, which it most likely is, you write past the end of the array when you create the arrays for each row. Writing past the end of allocated memory invokes undefined behavior.
Since you're creating an array of int *, use that for the size of each element:
matrix = calloc(sizeof(int *), SIZE);
Also, don't cast the return value of malloc/realloc/calloc, as that can mask a bug if you forget to #include <stdlib.h>
The code uses calloc(sizeof(int), SIZE), but the actual datatype in the structure is int *, leading to insufficient memory allocation on some systems (mine gives int size as 4 and int * size as 8).
Here's a rewrite suggestion (we'll swap size parameters in the calloc call per its header):
int main(int argc, char const *argv[]) {
int **matrix;
if (!(matrix = calloc(SIZE, sizeof(*matrix)))) {
fprintf(stderr, "calloc failed");
return 1;
}
for (int i = 0; i < SIZE; ++i) {
if (!(matrix[i] = calloc(SIZE, sizeof(*(matrix[i]))))) {
fprintf(stderr, "calloc failed");
return 1;
}
}
printf("%s\n", "Matrix initialized.");
printMatrix(matrix);
return 0;
}
Here, we use *matrix and *matrix[i] instead of hard coding the types int * and int respectively. This can help us avoid bugs and hunting for locations to change code if we need to make type adjustments at some point.
We also check that calloc succeeds by testing that the pointer is non-NULL. Failing to do so can introduce difficult-to-find bugs due to undefined behavior.
Note Do I cast the result of malloc?.
Reference manual describes calloc as:
void* calloc (size_t num, size_t size);
So, calloc takes firstly num of elements and then size of a particular element
Try:
matrix = (int **) calloc(SIZE, sizeof(int *));
I am trying to read and print using struct pointer which has pointer members. So I am trying to read and print array of double struct pointers.
I tried the folowing but it is giving me error saying "Access violation writing location (somewhere in memory)"
How can I allocate memory dynamically for this?
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
typedef struct template{
char *name;
int *birthdate;
int *phoneNum;
} detailsOf;
void inputValue(detailsOf **person, int maxSize);
int main() {
detailsOf **person;
int maxSize = 0, menu = 0;
printf("Max:");
scanf("%d", &maxSize);
person = (detailsOf **)malloc(maxSize * sizeof(detailsOf **));
if (person == NULL) {
printf("Failed to allocate");
exit(0);
}
for (int i = 0; i < maxSize; i++) {
person[i]->name = (char *)calloc(21, sizeof(char ));
person[i]->birthdate = (int *)calloc(8, sizeof(int ));
person[i]->phoneNum = (int *)calloc(16, sizeof(int ));
}
inputValue(person, maxSize);
for (int i = 0; i < maxSize; i++) {
free(person[i]);
for (int j = 0; j < 21; j++) {
free(person[i]->name[j]);
}
for (int j = 0; j < 15; j++) {
free(person[i]->phoneNum[j]);
}
for (int j = 0; j < 8; j++) {
free(person[i]->birthdate[j]);
}
}
return 0;
}
void inputValue(detailsOf **person, int maxSize) {
for (int i = 0; i < maxSize; i++) {
printf("Name of %d", i + 1);
scanf("%s", person[i]->name);
for (int j = 0; j < 8; j++) {
printf("Birth %d:", i + 1);
scanf("%d", person[i]->birthdate[j]);
}
for (int k = 0; k < 8; k++) {
printf("Phone %d:", i + 1);
scanf("%d", person[i]->phoneNum[k]);
}
}
printf("SUCCESS\n");
}
person = (detailsOf **)malloc(maxSize * sizeof(detailsOf **));
should be
person = malloc(maxSize * sizeof(detailsOf *));
Then, this allocated memory to hold pointers to detailsOf but you never allocate memory for each detailsOf
for(int i=0; i<maxSize; i++)
{
person[i]=malloc(sizeof(detailsOf));
}
Also your freeing of memory should be
for (int i = 0; i < maxSize; i++)
{
free(person[i]->name);
free(person[i]->phoneNum);
free(person[i]->birthdate);
free(person[i]);
}
free(person);
Remember while freeing just match your free calls with malloc calls.
Rule is simple -- a pointer is uninitialized until it has had a valid address assigned to it, or memory has been allocated within which to store things and the starting address for the new block of memory assigned to it.
You allocate maxSize pointers for person, but then fail to allocate a struct for each person[i] before allocating for name, etc..
So you must allocate a struct, e.g. pointer[i] = malloc (sizeof *pointer[i]) before attempting to allocate person[i]->name = calloc(21, sizeof(char ));, ...
Also note, if you allocate based on the size of the derefernced pointer -- you will never get your allocation wrong, (your allocation of person is only correct as the result of happy-accident), instead, e.g.
person = malloc (maxSize * sizeof *person);
...
person[i] = malloc (sizeof *person[i]);
(and note a [] or -> counts as a dereference)
person[i]->name = calloc (21, sizeof *person[i]->name);
There is no need to cast the return of malloc, it is unnecessary. See: Do I cast the result of malloc?
person = (detailsOf **)malloc(maxSize * sizeof(detailsOf **));
This allocates an array of double pointers to type detailsOf with array size as maxSize.
sizeof(detailsOf**) is the size of an address, it does not give you the size of your user-defined datatype detailsOf.
Also, double pointer means, it is an address location which will store the address of another pointer which points to the memory location of detailsOf
/* if you want to use double pointer then */
detailsOf **dptr; // two dimensional array of detailsOf */
detailsOf *sptr; /* one dimentional array of detailsOf */
/* This allocates the memory for storing 3 detailsOf struct data */
sptr = malloc(3 * sizeof(detailsOf));
dptr = &sptr;
/* Now to access double ptr */
for (int i = 0; i < 3; ++i) {
dptr[0][i].birthdate = malloc(3 * sizeof(int));
}
for (int i = 0; i < 3; ++i) {
dptr[0][i].birthdate[0] = i;
dptr[0][i].birthdate[1] = i + 10;
dptr[0][i].birthdate[2] = i + 1990;
}
for (int i = 0; i < 3; ++i) {
printf("%d\\", dptr[0][i].birthdate[0]);
printf("%d\\", dptr[0][i].birthdate[1]);
printf("%d\n", dptr[0][i].birthdate[2]);
}
/* Not to free the double pointer,
* you have to free the inner pointer first then the outer pointers
* Easy to remember is to free in reverse order of your allocation order
*/
for (int i = 0; i < 3; ++i) {
free(dptr[0][i].birthdate);
free(dptr[0]);
/* free(dptr); this is not needed in this example because
* dptr is pointer to address of a local variable,
* but if it points to address of another array of detailOf*
* then this free is needed
*/
}
In your case, you have just an array of pointer and not an array of double pointers.
The question is how to correctly allocate/free the memory in this example:
void test(char*** array, int* count) {
*array = malloc(sizeof(char*) * MAX_ARRAY);
while (...) {
(*array)[i] = (char*)malloc(strlen(fooString));
}
}
call of the function:
char** array;
int count;
test(&array, &count);
// now free the memory - i think i have to?
for(i = 0; i < count; i++) {
free(array[i]); // <-- crash here
}
free(array);
It looks like that array[0] has a different address inside the test-function than outside. How can this be? Looks like i misunderstood sth, because the address of array is the same outside and inside the function.
Edit: The Problem is that i am not able to free the allocated memory (see "crash here" in code). Why? And how will it work?
Instead of
void test(char*** array, int* count) {
*array = malloc(sizeof(char*) * MAX_ARRAY);
while (...) {
(*array)[i] = (char*)malloc(strlen(fooString));
}
}
do
void test(char*** array, int count) {
*array = malloc(sizeof(char*) * count); // number of pointers
for (int i = 0; i < count; ++i)
{
(*array)[i] = malloc(strlen(fooString));
}
}
although i am not sure about what fooString is since you don't show the decl/def. Normally you would allocate one byte extra for the \0
(*array)[i] = malloc(strlen(fooString) + 1)
this seems to work
#include <stdio.h>
#include <inttypes.h>
#include <malloc.h>
#include <string.h>
char fooString[256];
void test(char*** array, int count)
{
int i = 0;
*array = malloc(sizeof(char*) * count);
for (i = 0; i < count; ++i)
{
(*array)[i] = malloc(strlen(fooString)+1);
}
}
int main()
{
char** array = NULL;
int count = 100;
int i = 0;
test(&array, count);
for(i = 0; i < count;++i)
{
free(array[i]);
}
free(array);
return 0;
}
For your particular problem:
You allocate (*array)[i] which is a char* to strlen(fooString) which is usually equivalent to sizeof(char) * strlen(fooString) : this is error prone. You should use sizeof(*((*array)[i])) in this case to be sure not to miss the correct type.
To free it, loop from i = 0 to i < MAX_ARRAY and call free(array[i])
What you put in place of ... in your code is very important.
In general, when allocating memory, be sure to respect these general ideas:
If a functions allocates memory it frees it itself except when it is needed outside afterwards.
If a function allocates memory needed outside afterwards, it does just this.
This allows for better code architecture and easier freeing of the memory.
For example:
First point:
void foo()
{
char *a;
a = malloc(sizeof(*a) * 5);
a[0] = 'a';
a[1] = 'b';
a[2] = 'c';
a[3] = 'd';
a[4] = 0; //or '\0' if you prefer
do_something_cool(a);
free(a);
}
The function foo allocates memory, processes it, and frees it.
Second point:
char *halfstrdup(char *str)
{
int len;
int i;
char *newstr;
len = strlen(str);
newstr = malloc(sizeof(*newstr) * len / 2)
for (i = 0; i < len; i++)
{
if ((i % 2) == 0)
newstr[i / 2] = str[i];
}
return (newstr);
}
void foo2()
{
char *half;
half = halfstrdup("Hello, world !");
do_something_cooler(half);
free(half);
}
The function halfstrdup just allocates and sets the memory you need and returns it, the function foo2 allocates memory through the use of halfstrdup, then uses it and frees it.
Do not forget to free before losing track of your pointers, for example after returning from foo or foo2, you won't be able to free the allocated memory.