I'm new to programming and am having difficulty with arrays. I've declared the array but when I go to print an element of the array I get a very different number (possibly a memory address?).
#include <stdio.h>
int main()
{
int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
printf("%d", &array[3]);
return 0
}
Then it prints 6356748 instead of "3." What am I doing wrong?
Use:
printf("%d", array[3]);
When you use &variable, it returns the address of the variable.
That's because you are printing the address:
printf("%d", &array[3]); // note the use of &
Use this to print the value:
printf("%d", array[3]); // no & used
using &array[3] you are not refearing to the value array[3] (you are using a pointer, that is a reference to an address of the memory, you will know it later). You simply need to remove the & :
printf("%d", array[3]);
Related
I have this small piece of code:
uint64_t test[] = {1, 2, 3, 4, 5};
printf("test value: %llu\n", test);
I try to print the test array, and it gives me this number:
test value: 140732916721552
Can someone explain this and how an uint64_t array works? Thank you
In your code
uint64_t test[] = {1, 2, 3, 4, 5};
printf("test value: %llu\n", test);
%llu tells printf that it shall print a long long unsigned integer. The test part of the printf statement pass a pointer to the first element of the array to printf. In other words, there is a mismatch between what you are passing (a pointer) and what you tell printf to print (long long unsigned).
In C such a mismatch leads to "undefined behavior". So in general it's not possible to say what will be printed. Any print out will be legal from a C standard point of view. No print out would also be legal. A program crash would be legal. Anything... would be legal.
It's impossible to say what goes on in general. On a specific system, it's possible to dig into the low level things and figure out what is going on. On my system the printed value corresponds to the address of the first array element interpreted as a long long unsigned integer. But don't rely on that. Other systems may do something completely different.
The code below shows how to correctly print the address of the array and the array elements.
#include <stdio.h>
#include <inttypes.h>
int main(void)
{
uint64_t test[] = {1, 2, 3, 4, 5};
// Print the address where the array is located
printf("Address of test value is %p\n", (void*)test);
// Print the values of the array elements
size_t sz = sizeof test / sizeof test[0];
for (size_t i = 0; i < sz; ++i)
printf("test[%zu] is %" PRIu64 "\n", i, test[i]);
return 0;
}
Output (note: address may differ in every invocation):
Address of test value is 0x7ffc4ace5730
test[0] is 1
test[1] is 2
test[2] is 3
test[3] is 4
test[4] is 5
When you define an array like this in C, what you are actually doing is storing each of these values sequentially on the stack as separate uint64_ts. The value assigned to the test identifier is then a pointer to the first of these values, a uint64_t* rather than a uint64_t. When you print test, you are printing the pointer rather than any of the elements, i.e. the memory address of the first element in your array.
The [] notation is equivalent to
*(test + i)
i.e. it dereferences a pointer to the ith element.
I have an array made up of arbitrary length arrays.
int foo[] = {99, 1, 2};
int baz[] = {9, 8};
int tar[] = {-1, -2, -3, -4, -5, -6};
int *stuff[] = {foo, baz, tar}
I do not know the size of any of these arrays, I need to discover the size using sizeof() but I am getting strange results that do not seem to make sense when I compare them.
For example when I print the memory locations they are the same:
printf ("%p ", foo);
printf ("%p ", stuff[0]);
> 0x7ffef86f8de4 0x7ffef86f8de4
And when I print the first values of the array they are the same:
printf ("%d ", foo[0]);
printf ("%d ", stuff[0][0]);
> 99 99
However, here is the problem, when compare them with sizeof() they are NOT the same:
printf ("%lu ", sizeof(foo)/sizeof(foo[0]));
printf ("%lu ", sizeof(stuff[0])/sizeof(stuff[0][0]));
> 3 2
The problem is that you don't have an array of arrays, you have an array of pointers. So sizeof(stuff[0]) gives you the size of a pointer, not the size of the array that pointer points at. Once you convert an array to a pointer (which happens pretty much any time you use the array, since you can't really do much of anything with arrays themselves), the size of the array is lost.
I was finding the output of the following C program, which I found on GeeksforGeeks. Here's the program:
#include <stdio.h>
void fun(int ptr[])
{
int i;
unsigned int n = sizeof(ptr)/sizeof(ptr[0]);
for (i=0; i<n; i++)
printf("%d ", ptr[i]);
}
// Driver program
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
fun(arr);
return 0;
}
The output of this code was "1 2". But according to me, the output should be just 1. Here is my interpretation of this code:
Firstly, the main function will run, in which after declaring the array "arr", next statement will execute which contains the statement fun(arr).
In that statement, the function "fun" will be called with the argument arr, which contains the address of the first element of the array.
After that, under the function fun, there is a pointer ptr as a parameter. When this function will execute, then the value of n will be calculated as 1 since here the size of ptr is 4 and the size of ptr[0] is also 4.
Next, the loop will run only once since the value of n is 1 and that's why only '1' will get printed since it is the value of ptr[0].
Please help me to find out where I am wrong.
[....] the value of n will be calculated as 1 since here the size of ptr is 4 and the size of ptr[0] is also 4.
Well, that's common, but not guaranteed.
sizeof(ptr) could very well be, result in 8, which is likely in your case, while sizeof(int) can evaluate to 4, resulting a value of 2 for n. This depends on (and varies with) your environment and used implementation.
Try printing them separately, like
printf("Pointer size :%zu\n", sizeof(ptr));
printf("Element size: %zu\n", sizeof(ptr[0]));
and see for yourself.
The size of a pointer on modern platforms is commonly either 4 or 8 bytes.
On a 32-bit platform it's likely that sizeof(ptr) == 4 and n == 1.
On a 64-bit platform it's likely that sizeof(ptr) == 8 and n == 2.
I am trying to understand how malloc works. I did a program searches for the largest element in a one dimensional array int.
This is the code.
#include <stdlib.h>
#include <stdio.h>
void largest_element(int *nbr)
{
int i;
int n;
int m;
i = 1;
nbr = (int*)malloc(sizeof(nbr) + 8);
while (i < 8)
{
if (*nbr < *(nbr + i))
*nbr = *(nbr + i);
i++;
}
printf("%d ", *nbr);
}
int main(void)
{
int i;
int tab[8] = {11, 2, 4, 5, 9, 7, 8, 1};
int n = sizeof(tab)/sizeof(int);
i = 0;
largest_element(&tab[8]);
return(0);
}
The program works without malloc but how can I make it work with malloc? What did I do wrong and why does my code only give me garbage numbers?
I think you are lost with pointers and arrays so you can not understand malloc properly (no offense, everyone who is learning C do the same mistake).
Let's take your main function. When you run:
int tab[8] = {11, 2, 4, 5, 9, 7, 8, 1};
You staticly allocate an array of 8 integers and you fill it with your numbers.
The dynamic equivalent would be:
int* tab = malloc(sizeof(int) * 8);
tab[0] = 11;
tab[1] = 2;
/// Etc...
tab[7] = 1;
First thing: the first element of an array has the index 0. So in your largest_element function, i should be initialized at 0 instead of 1.
The reason is, when you deal with array, you deal with pointers. In your case, tab is a pointer to the first element of the array. So, when you do tab[3], you get the forth element of your array.
Second thing: when you do:
largest_element(&tab[8]);
You send to your function the eighth element after the begining of your array. The problem is: you do not own this memory area! You own the memory only until tab[7].
If you want to send the complete array to your function, just use:
largest_element(tab);
Now, let's talk about your largest_element function.
You do not need to call malloc here since the memory is already allocated
When you do *nbr = *(nbr + i); you change the value of the first element of your array. I think you wanted to do m = *(nbr + i); isn't it.
Why do you not use the nbr[i] instead of *(nbr + i)?
A correct implementation of this function would be something like (not tested):
void largest_element(int *nbr)
{
int i = 0;
int max = 0;
while (i < 8)
{
if (max < nbr[i])
max = nbr[i];
i++;
}
printf("%d ", m);
}
A last thing, using malloc involve using the function free to release the memory when you do not need it anymore.
What did I do wrong and why does my code only give me garbage numbers??
In largest_element(int *nbr) nbr points to the array tab in main (at least if you call it like this: largest_element(tab); instead of like this largest_element(&tab[8]);
Then you call nbr = (int*)malloc(sizeof(nbr) + 8); now nbr points to some allocated memory which has not been initialized and which contains garbage values. Now if you read from that memory it's normal that you get garbage values.
You simply don't need malloc for this problem, just as you don't need floating point math or file system related functions for this problem.
I have a problem with a character array in my c program.
The program immediately shutdown when I run it. I think the problem is somewhere with passing the character array in the function.
here's my code:
#include<stdio.h>
#include<string.h>
#define DAGEN 7
void inlezen(int[][DAGEN], char[][12]);
int main(void)
{
int i;
int temp[1][DAGEN];
char dagen[7][12];
strcpy(dagen[0], "MA");
strcpy(dagen[1], "DI");
strcpy(dagen[2], "WOE");
strcpy(dagen[3], "DO");
strcpy(dagen[4], "VR");
strcpy(dagen[5], "ZA");
strcpy(dagen[6], "ZO");
inlezen(temp, 1, DAGEN, dagen, 7, 12);
}
void inlezen(int t[][DAGEN], char d[][12])
{
int i;
for (i = 0; i < DAGEN; i++)
{
printf("Geef de temperatuur overdag van %s", d[i]);
scanf("%d%*c", &t[0][i]);
}
for (i = 0; i < DAGEN; i++)
{
printf("Geef de temperatuur 's avonds van %s", d[i]);
scanf("%d%*c", &t[1][i]);
}
}
I've edited my code, but it still doesn't work.
In your code
strcpy(dagen[6], "ZO");
you're accessing out of bound memory by using 6 as the index value. Your definition of dagen
char dagen[6][12];
only permits a valid access up to 5 as the first index.
]
By using 6, it invokes undefined behaviour.
FWIW, C uses 0 based indexing for arrays.
That said, the call
inlezen(temp, 1, DAGEN, dagen, 6, 12);
does not match the function signature, at all.
Finally, scanf() family expects a pointer to variable type of arguments for supplied format specifiers, so, the
scanf("%d%*c", t[0][i]);
statements should be actually
scanf("%d%*c", &t[0][i]);
and likewise.
void inlezen(int[][DAGEN], char[][12]);
See this prototype you declared
and what values you pass to it -inlezen(temp, 1, DAGEN, dagen, 6, 12); in main.
And this strcpy(dagen[6], "ZO"); .Declaration of array was char dagen[6][12]; so index can go from 0 to 5.You access out of bound memory ,thus invokes UB.Either remove this line or increase size to char dagen[7][12];
These statements -
scanf("%d%*c", t[0][i]);
.....
scanf("%d%*c", t[1][i]);
should be -
scanf("%d",&t[0][i]);
.....
scanf("%d",&t[1][i]);