my Excercice is to initalise space from the heap in function1(); and to create an array there. In the main I have to print the array. What have I done wrong?
CODE
#include <stdio.h>
#include <stdlib.h>
int functionOne(int size);
int main()
{
int size = 0,i;
scanf("%d",&size);
int *arrsize = functionOne(size);
printf("rueckgabe %d",arrsize);
int arr [*arrsize];
arr[0] = 7;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5;
for(i=0; i<size; i++)
{
printf("[%d]",arr[i]);
}
}
int functionOne(int size)
{
int *arr;
arr = NULL;
arr = malloc(size * sizeof(int));
return arr;
}
The thing is on the line printf("rueckgabe %d",arrsize); you are printing the address returned by other function - that too using wrong format specifier.
Suppose you allocated memory for 4 int using the other function functionOne and the memory of the allocated chunk is being returned - now when you do *arrsize you are basically accessing the 0th positional int value. But as it is uninitialized - the value of it is indeterminate.
Earlier you were declaring VLA with uninitialized value. This is undefined behavior. Also there is no meaning printing the contents of the variable length array unless you initialize them (i.e.,printf("[%d]",arr[i]);).
Return value of the function functionOne is int but you are returning int*.
There are many other things you can follow in the code, like correcting the indentation - checking the return value of malloc and changing the signature of main from int main() to int main(void).
I have added some demo code showing whatever I have mentioned above:
Edit:
#include <stdio.h>
#include <stdlib.h>
int* functionOne(int size);
int main(void)
{
int size = 0;
if( scanf("%d",&size)!= 1){
fprintf(stderr,"Error in input\n");
exit(EXIT_FAILURE);
}
if( size <= 0){
fprintf(stderr,"Error in input [size]\n");
exit(EXIT_FAILURE);
}
int *arr = functionOne(size);
for(size_t i = 0; i < size; i++){
arr[i]=i;
}
for(size_t i = 0; i<size; i++){
printf("arr[%zu] = %d \n",i,arr[i]);
}
free(arr);
return 0;
}
int* functionOne(int size)
{
int *arr;
arr = malloc(sizeof(int)*size);
if( arr == NULL && size > 0){
perror("malloc");
exit(EXIT_FAILURE);
}
return arr;
}
Related
#include <stdio.h>
#include <stdlib.h>
int find_lenght(int *arrr){
int i = 0;
while(arrr[i] != '\0'){
i++;
}
return i;
}
void init_array(int *arrr){
arrr=(int*)malloc(1*sizeof(int));
printf("New element:");
int lenght = find_lenght(arrr);
scanf("%d", &arrr[lenght]);
printf("Lenght = %d\n",lenght);
printf("Array elements are:\n");
for(int i = 0; i <= lenght; i++) {
printf("%d,", arrr[i]);
}
}
void print_array(int *arrr){
printf("Array elements are:\n");
int lenght = find_lenght(arrr);
for(int i = 0; i == lenght; i++) {
printf("%d,", arrr[i]);
}
}
int main() {
int *arr = NULL;
init_array(arr);
print_array(arr);
}
I don't know what am i missing here.
My point is to fill in and then print dynamic array
Also my taught is it's not filling the way it should, so it hasn't anything to print.
Your arr pointer in main is never assigned because your init_array assign the address of the allocated memory (the return value of malloc) to the input parameter arrr, which is, a local variable.
You have mainly two solutions to properly achieve what you want to do. The first one (the better one in my point of view), by making your init_array returning the allocated memory address to be assigned:
int* init_array()
{
int* retval = (int*)malloc(1*sizeof(int));
// ...
return retval;
}
int main()
{
int *arr = init_array(); //< assign arr with returned value
}
Another way is to make your init_array function taking a pointer to a pointer, so the function can assign this pointer:
void init_array(int** arrr)
{
(*arrr) = (int*)malloc(1*sizeof(int));
// ...
}
int main()
{
int* arr = NULL;
init_array(&arr); //< pass reference to arr
}
You need to pass the pointer to pointer to int to change passed pointer. Your for loop is invalid in print function. You need also to set the sentinel value yourself.
size_t find_length(const int *arrr)
{
size_t i = 0;
if(arrr)
while(arrr[i]) i++;
return i;
}
void add_element(int **arrr, int element)
{
size_t length = find_length(*arrr);
int *tmp = realloc(*arrr, (length + 2) * sizeof(**arrr));
if(tmp)
{
*arrr = tmp;
(*arrr)[length] = element;
(*arrr)[length + 1] = 0;
}
}
void print_array(const int *arrr)
{
printf("Array elements are:\n");
size_t lenght = find_length(arrr);
for(size_t i = 0; i < lenght; i++)
{
printf("arrr[%zu] = %d\n", i, arrr[i]);
}
}
int main(void) {
int *arr = NULL;
add_element(&arr, 5);
add_element(&arr, 15);
add_element(&arr, 25);
add_element(&arr, 35);
print_array(arr);
}
https://godbolt.org/z/drKej3KT5
the array on your main function is still NULL. the better way to do is just call the print_array() function after you initialize it. you just simply put print_array(arrr) inside init_array() and after the for loop statement.
The line
int lenght = find_lenght(arrr);
may invoke undefined behavior, because find_length requires its argument to be a pointer to the first element of a null-terminated int array. However, the content of the memory pointed to by arrr is indeterminate, because it has not been initialized. Therefore, it is not guaranteed to be null-terminated.
I'm trying to write a function which takes 2 arrays and their size (both same size) and returns an array with each number from the first array appearing the amount of times in the same index in the second array. Example: input: {2,5,3,7,8},{5,2,0,4,3},5 output: {2,2,2,2,2,5,5,7,7,7,7,8,8,8}
My current code:
#include <stdio.h>
#include <stdlib.h>
int* blowUpArray(int numArray[], int amountArray[], int size);
int* reallocateArr(int* arr, int currLogSize, int newSize);
int main() {
int arr1[] = {2,5,3,7,8},arr2[] = {5,2,0,4,3}
int* res;
res = blowUpArray(arr1,arr2,5);
for (int i = 0; i < 14; i++)
printf("%d ", res[i]);
return 0;
}
int* blowUpArray(int numArray[], int amountArray[], int size)
{
int i = 0,currSize = 0,j;
int* blownUp;
while (i < size)
{
blownUp = reallocateArr(numArray,currSize,amountArray[i]);
for (j = currSize; j < currSize + amountArray[i]; j++)
{
blownUp[j] = numArray[i];
}
currSize = currSize + amountArray[i];
i++;
}
return blownUp;
}
int* reallocateArr(int* arr, int currLogSize, int addedSize)
{
int* newArr;
int i;
newArr = (int*)malloc((currLogSize + addedSize) * sizeof(int));
if (newArr == NULL)
{
printf("Memory allocation failed.\n");
exit(1);
}
for (i = 0; i < currLogSize; i++)
newArr[i] = arr[i];
free(arr);
return newArr;
}
I'm getting this error:
malloc: *** error for object 0x7ffee644b6f0: pointer being freed was not allocated
malloc: *** set a breakpoint in malloc_error_break to debug
Any ideas?
The reallocateArr function is freeing the arr parameter. It is called like this:
reallocateArr(numArray,currSize,amountArray[i]);
Where numArray is a parameter to the function blowUpArray which is called like this:
res = blowUpArray(arr1,arr2,5);
Where arr is an array local to the main function. Because this array was declared as a local variable, you can't pass it to free.
You probably wanted to pass blownUp to reallocateArr:
reallocateArr(blownUp,currSize,amountArray[i]);
You should also initialize this variable to NULL:
int* blownUp = NULL;
So you can safely pass it to free on the first iteration of the loop in blowUpArray.
I tried to use dynamic allocation and I didnt sucsses to write it without warnings. I get debbug error with the 'free' function:
This is my program:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define size 1
int* symetri(int set1[size], int set2[size]);
int main() {
int* difference;
int set1[size], set2[size];
for (int i = 0; i < size; i++)
scanf("%d", &set1[i]);
for (int i = 0; i < size; i++)
scanf("%d", &set2[i]);
difference = symetri(set1, set2);
free(difference);
return 0;
}
int* symetri(int set1[size], int set2[size])
{
int* new_arr = (int*)malloc(size * sizeof(int));
while (new_arr == NULL)
new_arr = (int*)malloc(size * sizeof(int));
int counter = 0;
bool sym;
for (int i = 0; i < size; i++) {
new_arr[counter] = set1[i];
counter++;
}
new_arr[counter] = -1;
return new_arr;
}
If free crashes with an error message about heap corruption in a program this simple, it's almost certainly because you wrote to memory that doesn't belong to you. And you did, with this line at the end of symetri:
new_arr[counter] = -1;
You need to make your allocation of new_arr another sizeof(int) longer if you want to write to the end after looping over it.
Can someone tell me why do I get this segmentation fault?
Is it because I have set a pointer to NULL and passed it to a function?
Should I use arrays or pointers when I want to send an array to function?
#include <stdlib.h>
#include <stdio.h>
int* ComputeFibo(int _size);
void PrintFibo(int* _arr, int _size);
int main (int argc, char* argv[])
{
int* arr = NULL;
int n = 0;
printf("Please enter Fibonacci size:");
scanf("%d", &n);
arr = ComputeFibo(n);
PrintFibo(arr, n);
return 0;
}
int* ComputeFibo(int _size)
{
int sum = 0;
int indx = 0;
int* arr = NULL;
arr[indx] = 1;
for (indx = 1; indx < _size; ++indx)
{
arr[indx] = arr[indx - 1] + sum;
sum = arr[indx - 1];
}
return arr;
}
void PrintFibo(int* _arr, int _size)
{
int indx = 0;
for (; indx < _size; ++indx)
{
printf("%d\t", _arr[indx]);
}
}
I would love to get an answer with a good explanation for that.
The problematic statement is:
int* arr = NULL;
where arr is pointing at NULL and then you assign values to arr as if it's pointing to valid memory location.
You could fix it with:
int* arr = malloc(_size * sizeof *arr);
if (arr == NULL) { /* error *}
and then call free() on the returned pointer later.
arr = ComputeFibo(n);
PrintFibo(arr, n);
free(arr);
Also be aware that int can only represent limited values in C. So, for example, if you try to calculate upto 100 Fibonacci numbers, you are likely to run into integer overflow.
You tried to access index of a null pointer.
int* ComputeFibo(int _size)
{
int* arr = NULL;
arr[indx] = 1; //SIGF
...
}
I fixed your code if you want a reference.
#include <stdlib.h>
#include <stdio.h>
void compute_fibo(int *_arr, int _size);
void print_fibo(int *_arr, int _size);
int main(int argc, char *argv[]) {
int n = 0;
printf("Please enter Fibonacci size:");
scanf("%d", &n);
int *arr = (int *) malloc(sizeof(int) * n);
if (arr == NULL) return 1;
compute_fibo(arr, n);
print_fibo(arr, n);
free(arr);
return 0;
}
void compute_fibo(int *_arr, int _size) {
_arr[0] = 1;
_arr[1] = 1;
for (int index = 2; index < _size; index++) {
_arr[index] = _arr[index - 1] + _arr[index - 2];
}
}
void print_fibo(int *_arr, int _size) {
for (int index = 0; index < _size; ++index) {
printf("%d\t", _arr[index]);
}
}
output:
Please enter Fibonacci size:10
1 1 2 3 5 8 13 21 34 55
i'm trying to figure out how to return an array from a function in the main().
I'm using C language.
Here is my code.
#include <stdio.h>
int *initArray(int n){
int i;
int *array[n];
for(i = 0; i < n; i++){
array[i] = i*2;
}
return array;
}
main(){
int i, n = 5;
int *array[n];
array[n] = initArray(n);
printf("Here is the array: ");
for(i = 0; i < n; i++){
printf("%d ", array[i]);
}
printf("\n\n");
}
And this is the errors the console gives me:
2.c: In function ‘initArray’:
2.c:8:13: warning: assignment makes pointer from integer without a cast [enabled by default]
array[i] = i*2;
^
2.c:11:3: warning: return from incompatible pointer type [enabled by default]
return array;
^
2.c:11:3: warning: function returns address of local variable [-Wreturn-local-addr]
2.c: In function ‘main’:
2.c:23:4: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("%d ", array[i]);
^
It's impossible!
I hate being a noob :(
If you could help, with explanations, I would appreciate! :D
Edit: iharob's answer is better than mine. Check his answer first.
Edit #2: I'm going to try to explain why your code is wrong
Consider the 2nd line of main() in your question:
int *array[n];
Let's try to read it backwards.
[n]
says we have an array that contains n elements. We don't know what type those elements are and what the name of the array is, but we know we have an array of size n.
array[n]
says your array is called array.
* array[n]
says you have a pointer to an array. The array that is being pointed to is called 'array' and has a size of n.
int * array[n];
says you have a pointer to an integer array called 'array' of size n.
At this point, you're 3/4 way to making a 2d array, since 2d arrays consist of a list of pointers to arrays. You don't want that.
Instead, what you need is:
int * array;
At this point, we need to examine your function, initArray:
int *initArray(int n){
int i;
int *array[n];
for(i = 0; i < n; i++){
array[i] = i*2;
}
return array;
}
The second line of initArray has the same mistake as the second line of main. Make it
int * array;
Now, here comes the part that's harder to explain.
int * array;
doesn't allocate space for an array. At this point, it's a humble pointer. So, how do we allocate space for an array? We use malloc()
int * array = malloc(sizeof(int));
allocates space for only one integer value. At this point, it's more a variable than an array:
[0]
int * array = malloc(sizeof(int) * n);
allocates space for n integer variables, making it an array:
e.g. n = 5:
[0][0][0][0][0]
Note:The values in the real array are probably garbage values, because malloc doesn't zero out the memory, unlike calloc. The 0s are there for simplicity.
However, malloc doesnt always work, which is why you need to check it's return value:
(malloc will make array = NULL if it isn't successful)
if (array == NULL)
return NULL;
You then need to check the value of initArray.
#include <stdio.h>
#include <stdlib.h>
int *initArray(int n){
int i;
int *array = malloc(sizeof(int) * n);
if (array == NULL)
return NULL;
for(i = 0; i < n; i++){
array[i] = i*2;
}
return array;
}
int main(){
int i, n = 5;
int *array = initArray(n);
if (array == NULL)
return 1;
printf("Here is the array: ");
for(i = 0; i < n; i++){
printf("%d ", array[i]);
}
free(array);
printf("\n\n");
return 0;
}
You can't just return an array like that. You need to make a dynamically allocated array in order to do that. Also, why did you use a 2d array anyway?
int array[5];
is basically (not completely) the same as:
int * array = malloc(sizeof(int) * 5);
The latter is a bit more flexible in that you can resize the memory that was allocated with malloc and you can return pointers from functions, like what the code I posted does.
Beware, though, because dynamic memory allocation is something you don't wanna get into if you're not ready for tons of pain and debugging :)
Also, free() anything that has been malloc'd after you're done using it and you should always check the return value for malloc() before using a pointer that has been allocated with it.
Thanks to iharob for reminding me to include this in the answer
Do you want to initialize the array? You can try it like this.
#include <stdio.h>
void initArray(int *p,int n)
{
int i;
for(i = 0; i < n; i++)
{
*(p+i) = i*2;
}
}
void main(void)
{
int i, n = 5;
int array[n];
initArray(array,n);
printf("Here is the array: ");
for(i = 0; i < n; i++)
{
printf("%d ", array[i]);
}
printf("\n\n");
}
If you don't want to get in trouble learning malloc and dynamic memory allocation you can try this
#include <stdio.h>
void initArray(int n, int array[n]) {
int i;
for (i = 0 ; i < n ; i++) {
array[i] = i * 2;
}
}
int main() { /* main should return int */
int i, n = 5;
int array[n];
initArray(n, array);
printf("Here is the array: ");
for(i = 0 ; i < n ; i++) {
printf("%d ", array[i]);
}
printf("\n\n");
return 0;
}
as you see, you don't need to return the array, if you declare it in main(), and pass it to the function you can just modify the values directly in the function.
If you want to use pointers, then
#include <stdio.h>
int *initArray(int n) {
int i;
int *array;
array = malloc(n * sizeof(*array));
if (array == NULL) /* you should always check malloc success */
return NULL;
for (i = 0 ; i < n ; i++) {
array[i] = i * 2;
}
return array;
}
int main() { /* main should return int */
int i, n = 5;
int *array;
array = initArray(n);
if (array == NULL) /* if null is returned, you can't dereference the pointer */
return -1;
printf("Here is the array: ");
for(i = 0 ; i < n ; i++) {
printf("%d ", array[i]);
}
free(array); /* you sould free the malloced pointer or you will have a memory leak */
printf("\n\n");
return 0;
}