#include<stdio.h>
int main() {
int arr[10] = { 11 , [9] = 22 };
int i;
arr[13] = 2452;
arr[10] = 1212;
for(i = 0; i < 15; i++) {
printf("arr[%i] %i\n " , i, arr[i]);
}
return 0;
}
The output it is generating as follows:
arr[0] 11
arr[1] 0
arr[2] 0
arr[3] 0
arr[4] 0
arr[5] 0
arr[6] 0
arr[7] 0
arr[8] 0
arr[9] 22
arr[10] 10
arr[11] -1216806924
arr[12] 0
arr[13] 2452
arr[14] -1218431789
output of arr [10] and arr [13] I'm unable to understand.
arr[] size is 10, so arr[0] to [9] values are valid. everything else is rubish, you are accesing memory out of bounds
I will try to explain. It seems that the compiler placed local variables in the stack in the following way as they were declared
int arr[10] = { 11 , [9] = 22 };
int i;
In this case object int i occupies memory that corresponds to arr + 10 (actual elements of the array occupy memory from arr + 0 to arr + 9 inclusively)
Thus when in the loop you output arr[10] then in fact you output object i that in this moment is equal naturally to 10.
That is at first you set i to 1212 (arr[10] = 1212;) and then in the loop the variable is overwritten i and arr[10[ share the same memory.
As for arr[13] then the program outputs its value as it was set before the loop.
Of course your program has undefined behaviour because you are overwritting memory beyond the array.
Related
Trace the execution of the following program? What will be the final values of array be printed?
I have to trace the following C code and write the output. I ran the program and the output is different than what I expected. Most likely I traced it incorrectly but I can't find what I am doing wrong.
*I didn't write the code. The code was included in the question.
#include <stdio.h>
#include <math.h>
int main()
{
int a[7]={2,0,0,0,0,0,0};
int i=1;
for (i=1; i<7; i++)
{
if (i<3)
a[i] = a[i-1]+i+1; //when i=1, a[1]= a[1-1]+1+1 -> a[0]+1+1 -> 2+1+1=4
//a[1] is now 4
//when i=2, a[2]= a[2-1]+1+1 -> a[1]+1+1 -> 4+2+1=7
//a[2] is now 7
else if (i<5)
a[i] = a[i-2]+1; //when i=3, a[3]= a[3-2]+1 -> a[1]+1 -> 4+1=6
//a[3] is now 6 but it should be 11??? 11
//when i=4, a[4]= a[4-1]+1 -> a[2]+1 -> 7+1=8
//a[4] is now 8 but it should be 16??? 16
else
a[i] = a[i-2]*i-2; //when i=5, a[5]= a[5-2]*5-2 -> a[3]*3 -> 6*3= 18
//a[5] is now 18 but it should be 22???
//when i=6, a[6]= a[6-1]*6-2 -> a[5]*4 -> 18*4= 72
//a[6] is now 8 but it should be 29????
}
for (i=0; i<7; i++)
printf("a[%d] = %d\n",i,a[i]); //prints a[0] = 2 first because i=0 in the above loop
}
Actual Output:
a[0] = 2
a[1] = 4
a[2] = 7
a[3] = 11
a[4] = 16
a[5] = 22
a[6] = 29
I copied your code and ran it, this is my output:
a[0] = 2
a[1] = 4
a[2] = 7
a[3] = 5
a[4] = 8
a[5] = 23
a[6] = 46
#include <stdio.h>
#include <string.h>
int main(void)
{
int arr2d[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
int* arr = (int*)arr2d;
int i = 0;
for (i = 0; i < 9; i++)
{
printf("%d ", arr[i]);
}
printf("\n\n");
int arr1[] = { 11,12 };
int arr2[] = {13, 14, 15, 16};
int arr3[] = { 17, 18, 19 };
int * parr[3] = { arr1,arr2,arr3 };
int *parr1 = (int*)parr;
for (i = 0; i < 9; i++)
{
printf("%d ", parr1[i]);
}
return 0;
here at the start i converted from two-dimensional array and printed it but after that i did it with array of pointer and it didn't work can someone please explain it?
You might want to learn how these objects are laid out in memory:
int array[][3] = { {1,2,3}, {4,5,6}, {7,8,9} };
int *p_array = (int *) array;
This creates an object array of type int[][3] in memory (in this case stack) physically laid out in a hypothetical (16-bit word size) architecture as:
array 0x8000: 0x0001
0x8002: 0x0002
0x8004: 0x0003
0x8006: 0x0004
0x8008: 0x0005
0x800A: 0x0006
0x800C: 0x0007
0x800E: 0x0008
0x8010: 0x0009
p_array 0x8012: 0x8000
Where 0x8000 denotes the imaginary stack address of array.
However, in your second example:
int array1[] = { 11, 12 };
int array2[] = { 13, 14, 15, 16 };
int array3[] = { 17, 18, 19 };
int *array_pointers[] = { array1, array2, array3 };
int *array_pointers2 = (int*) array_pointers;
Here array_pointers is of type int *[] which means it is a pointer to array of ints. And the memory layout would be like the following:
array1 0x8000: 0x000B
0x8002: 0x000C
array2 0x8004: 0x000D
0x8006: 0x000E
0x8008: 0x000F
0x800A: 0x0010
array3 0x800C: 0x0011
0x800E: 0x0012
0x8010: 0x0013
and
array_pointers: 0x8012: 0x8000 address of array1
0x8014: 0x8004 address of array2
0x8016: 0x800C address of array3
array_pointers2: 0x8018: 0x8012 address of array_pointers
So when you try to print the contents of array_pointers2, which now contain pointers to array of ints, you will print the address values rather than the numbers they point to.
Here is an example that outputs the memory address of those objects:
https://ideone.com/T52Ow0
Which prints:
array 0x7ffeda682090: 0x00000000000001
0x7ffeda682094: 0x00000000000002
0x7ffeda682098: 0x00000000000003
0x7ffeda68209c: 0x00000000000004
0x7ffeda6820a0: 0x00000000000005
0x7ffeda6820a4: 0x00000000000006
0x7ffeda6820a8: 0x00000000000007
0x7ffeda6820ac: 0x00000000000008
0x7ffeda6820b0: 0x00000000000009
p_array 0x7ffeda682038: 0x007ffeda682090
array1 0x7ffeda68204c: 0x0000000000000b
0x7ffeda682050: 0x0000000000000c
array2 0x7ffeda682060: 0x0000000000000d
0x7ffeda682064: 0x0000000000000e
0x7ffeda682068: 0x0000000000000f
0x7ffeda68206c: 0x00000000000010
array3 0x7ffeda682054: 0x00000000000011
0x7ffeda682058: 0x00000000000012
0x7ffeda68205c: 0x00000000000013
array_poin 0x7ffeda682070: 0x007ffeda68204c
0x7ffeda682078: 0x007ffeda682060
0x7ffeda682080: 0x007ffeda682054
array_poi2 0x7ffeda682040: 0x007ffeda682070
on my computer.
Source code for that in case external link expires:
#include <stdio.h>
#include <string.h>
int main(void)
{
int array[][3] = { {1,2,3}, {4,5,6}, {7,8,9} };
int *p_array = (int*) array;
for (int i = 0; i < 9; i++) {
printf("%-10s %08p: %016p\n", i == 0 ? "array" : "", &p_array[i], p_array[i]);
}
printf("%-10s %08p: %016p\n", "p_array", &p_array, p_array);
int array1[] = { 11, 12 };
int array2[] = { 13, 14, 15, 16 };
int array3[] = { 17, 18, 19 };
int *array_pointers[] = { array1, array2, array3 };
int *array_pointers2 = (int*) array_pointers;
putchar('\n');
for (int i = 0; i < sizeof(array1) / sizeof(array1[0]); i++) {
printf("%-10s %08p: %016p\n", i == 0 ? "array1" : "", &array1[i], array1[i]);
}
for (int i = 0; i < sizeof(array2) / sizeof(array2[0]); i++) {
printf("%-10s %08p: %016p\n", i == 0 ? "array2" : "", &array2[i], array2[i]);
}
for (int i = 0; i < sizeof(array3) / sizeof(array3[0]); i++) {
printf("%-10s %08p: %016p\n", i == 0 ? "array3" : "", &array3[i], array3[i]);
}
for (int i = 0; i < sizeof(array_pointers) / sizeof(array_pointers[0]); i++) {
printf("%-10s %08p: %016p\n", i == 0 ? "array_poin" : "", &array_pointers[i], array_pointers[i]);
}
printf("%-10s %08p: %016p\n", "array_poi2", &array_pointers2, array_pointers2);
return 0;
}
You cannot simply use int * with a single loop from 0 to N as you would with contiguous arrays of integers like arr2d since:
the pointers may be far apart in memory
you need to dereference each of those pointers, which you can't do with int * since int * will interpret A[i] as an int, not a pointer.
To understand how to fix it, you might want to understand how things are laid out in memory. Let's start with an easy one: your arr2d declaration. Assuming a 2-byte int, here's how it might look:
arr2d # 0x8000
=======================
| arr2d[0] # 0x8000 |
| ----------------- |
| | 1 2 3 | |
| ----------------- |
| #8000 #8002 #8004 |
| |
| arr2d[1] # 0x8006 |
| ----------------- |
| | 4 5 6 | |
| ----------------- |
| #8006 #8008 #800A |
| |
| arr2d[0] # 0x800C |
| ----------------- |
| | 7 8 9 | |
| ----------------- |
| #800C #800E #8010 |
=======================
Notice how the memory addresses from one item to the next are all 2 bytes apart? This is one reason why you can do int* arr = (int*)arr2d and print arr[i] to get the values you want. The other reason is the fact that you're storing integers.
Now let's look at parr and arr1, arr2, and arr3:
arr1 # 0xA000
----------
| 11 12 |
----------
#A000 #A002
arr2 # 0xB000
-------------------------
| 13 14 15 16 |
-------------------------
#B000 #B002 #B004 #B006
arr3 # 0xC000
------------------
| 17 18 19 |
------------------
#C000 #C002 #C004
parr # 0xE000
------------------------
| #A000 #B000 #C000 |
| (arr1) (arr2) (arr3) |
------------------------
#E000 #E004 #E008
Remember what I said about arr2d storing integers? Well, parr stores pointers, so things work a bit differently. For one thing, you need to dereference a pointer using the * operator, but you're using int *parr1, so parr1[i] results in a pointer being interpreted incorrectly as an integer. Also notice the addresses of the integers increase by 2 in each array while the addresses of the pointers (#E000..#E008) increase by 4. In other words, you're interpreting a 4-byte pointer as a 2-byte integer, which can make your problem worse if your system is using different sizes for int and int *. If you declare int **parr1 = parr instead and use *parr1[i] for printing, things will be much better.
However, this will only print the first value in each array. That's because you're storing pointers to the first item in each array (because array decay turns arr1 into &arr1[0], arr2 into &arr2[0], and arr3 into &arr3[0]). Pointers have no element count because they're not arrays, and since you're storing a pointer to a single int rather than a pointer to an array, you're effectively removing the element count anyway. You'd need to keep track of the element count of each array yourself, perhaps in another array. Here's some modified code that fixes your problem:
// Only works for real arrays, not pointers returned by malloc/calloc.
#define ARRAY_COUNT(a) (sizeof (a) / sizeof (a)[0])
int arr1[] = { 11,12 };
int arr2[] = {13, 14, 15, 16};
int arr3[] = { 17, 18, 19 };
int * parr[3] = { arr1,arr2,arr3 };
int **parr1 = (int*)parr;
int counts[] = { ARRAY_COUNT(arr1), ARRAY_COUNT(arr2), ARRAY_COUNT(arr3) };
for (i = 0; i < ARRAY_COUNT(counts); i++)
{
for (j = 0; j < counts[i]; j++)
{
printf("%d ", parr1[i][j]);
}
}
Note that I used two loops: 1 for the counts and 1 for each array's content. If you really wanted, you could merge the two loops, but it's a bit more difficult to follow the logic:
i = 0;
j = 0;
while (i < ARRAY_COUNT(counts))
{
if (j < counts[i]) {
printf("%d ", parr1[i][j]);
j++;
} else {
i++;
j = 0;
}
}
I have to write a function to sort an array in the heap. This function should make a copy of the array, sort the copy, and return a pointer to the sorted copy. I tried qsort() but I get strange output. I'm sure it has something to do with the pointer but still can't figure it out.
This is my code so far:
int cmpfunc(const void * a, const void * b)
{
return ( *(int*)a - *(int*)b);
}
int sorted_copy(int* list[], size_t s)
{
int aList[s];
memcpy(aList,list,s);
printf("Array was copied successfuly to aList[] array\n\n");
printf("Before sorting the list is: \n");
for(int i = 0; i < s; i++)
printf("%d\n", aList[i]);
qsort(aList, s, sizeof(int), cmpfunc);
printf("After sorting the list is: \n");
for(int i = 0; i < s; i++)
{
printf("%d\n", aList[i]);
}
return *aList;
}
int main()
{
int list[10] = {4, 1, 2, 7, 3, 5, 6, 0, 8, 9};
sorted_copy(list,sizeof(list));
return 0;
}
An this the output I'm getting
Array was copied successfuly to aList[] array
Before sorting the list is:
4
1
2
7
3
5
6
0
8
9
0
0
0
0
3
0
0
0
268501009
32762
4199840
0
-1407817721
32762
12846904
0
1324151619
0
8
0
176
0
6487584
0
4199972
0
4200528
0
-1434081178
32762
After sorting the list is:
-1434081178
-1407817721
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
2
3
3
4
5
6
7
8
8
9
176
32762
32762
32762
4199840
4199972
4200528
6487584
12846904
268501009
1324151619
Process returned 0 (0x0) execution time : 0.281 s
Press any key to continue.
Well, the second parameter of sorted_copy() must be the number of elements of array passed as first parameter, and not its sizeof (the size of the object in memory bytes) I'm supposing you are using a 32 bit architecture, where an int is four bytes wide, and you are passing 40 as the array number of elements, not 10 which is the actual number of cells in the array.
Change
int main()
{
/* you don't need to specify the number of elements to declare
* the array if you are using an initializer that fully populates
* the array elements */
int list[10] = {4, 1, 2, 7, 3, 5, 6, 0, 8, 9};
sorted_copy(list,sizeof(list)); /* sizeof gives you the array
* size in bytes, not in number
* of elements */
return 0;
}
into
int main()
{
int list[] = {4, 1, 2, 7, 3, 5, 6, 0, 8, 9};
sorted_copy(list, sizeof list / sizeof list[0]);
return 0;
}
and you'll get the correct result.
I'm somewhat well-versed with C and I thought I had pointers all figured out until I ran into this problem. I'm creating an array-implemented stack of structs. Easy enough, but I'm running into a problem when my struct contains a dynamically allocated array.
The struct is:
typedef struct state {
int* S;
double prob;
} state_t;
Now say I'd like to create an array of 10 of those structs, each with an integer array of say 5 integers. I can allocate that array as:
state_t *newContents;
newContents = (state_t *)malloc((sizeof(state_t) + 5 * sizeof(int)) * 10);
And I can create a struct to go in the first slot:
state_t *root = malloc(sizeof *root + 5 * sizeof(int));
root->prob = 1.0;
root->S[0] = 3;
root->S[1] = 5;
root->S[2] = 7;
root->S[3] = 2;
root->S[4] = 0;
newContents[0] = *root;
But when I attempt to add a second struct, Seg fault. It's because the way the array is indexing is by the size of the struct without the int array, meaning each entry is 16 bytes long - 8 for the double + 8 for the pointer. I want it to instead index by 28 - 8 for the double and 4*5 for the ints. Does anyone know a way to access elements of this array correctly?
Thanks!
You're allocating your structs wrong. The struct itself is separate from its dynamically-allocated array and needs to be allocated separately:
// Allocate the structs.
state_t *newContents = malloc(10*sizeof(*newContents));
// Allocate the S array of the first struct.
newContents[0].S = malloc(5*sizeof(int));
newContents[0].S[0] = 3;
...
If you want a struct that actually contains an array of runtime-determined length, rather than pointing to one as your current struct does, you need a flexible array member:
struct state_t {
double prob;
int S[]; // No length specified!
};
Then you can malloc(sizeof(state_t) + n*sizeof(int)) and actually get a contiguous block of memory where the struct and its array are together. However, you can't put make an array of state_ts properly if you do this, since the compiler would have no idea where one struct ends and another begins.
Do this:
state_t *newContents;
newContents = malloc(sizeof(state_t)*10);
int i;
for (i=0;i<10;i++)
(newContents+i)->S=malloc(5 * sizeof(int));
If you want newContents to be an array of structs of size 10, then it should allocate size equal to sizeof(state_t)*10. The int *s within each struct should be allocated explicitly.
Using
Arrays of Length Zero and GCC extensions of it
proper type casting
proper pointer arithmetic
you could get what you want, more or less.
Here is my testing program (compiling with gcc -std=c99):
#include <stdio.h>
#include <stdlib.h>
typedef struct state {
double prob;
int S[];
} state_t;
int main(void) {
size_t stateSize;
state_t *newContents;
stateSize = sizeof(state_t) + 5*sizeof(int);
newContents = malloc(stateSize * 10);
for (int i = 0; i < 10; i++) {
state_t *state = (state_t *)((char *)newContents + i * stateSize);
state->prob = i;
for (int j = 0; j < 5; j++) {
state->S[j] = i * j;
}
}
for (int i = 0; i < 10; i++) {
state_t *state = (state_t *)((char *)newContents + i * stateSize);
printf("[%d] prob: %f\n", i, state->prob);
for (int j = 0; j < 5; j++) {
printf("\tS[%d]: %d\n", j, state->S[j]);
}
}
}
Run:
$ ./a.out
[0] prob: 0.000000
S[0]: 0
S[1]: 0
S[2]: 0
S[3]: 0
S[4]: 0
[1] prob: 1.000000
S[0]: 0
S[1]: 1
S[2]: 2
S[3]: 3
S[4]: 4
[2] prob: 2.000000
S[0]: 0
S[1]: 2
S[2]: 4
S[3]: 6
S[4]: 8
[3] prob: 3.000000
S[0]: 0
S[1]: 3
S[2]: 6
S[3]: 9
S[4]: 12
[4] prob: 4.000000
S[0]: 0
S[1]: 4
S[2]: 8
S[3]: 12
S[4]: 16
[5] prob: 5.000000
S[0]: 0
S[1]: 5
S[2]: 10
S[3]: 15
S[4]: 20
[6] prob: 6.000000
S[0]: 0
S[1]: 6
S[2]: 12
S[3]: 18
S[4]: 24
[7] prob: 7.000000
S[0]: 0
S[1]: 7
S[2]: 14
S[3]: 21
S[4]: 28
[8] prob: 8.000000
S[0]: 0
S[1]: 8
S[2]: 16
S[3]: 24
S[4]: 32
[9] prob: 9.000000
S[0]: 0
S[1]: 9
S[2]: 18
S[3]: 27
S[4]: 36
I'm new to C and programming in general, so I've studied a bit and wanted to make a simple program that validates personal numeric codes from my country. This is the program:
#include <stdio.h>
int validateCNP(char cnp[13]);
int main(int argc, const char * argv[])
{
char cnp[13];
printf("Introduceti CNP-ul:\n");
scanf("%s", cnp);
if(validateCNP(&cnp[0]) == 1) {
printf("CNP valid");
} else {
printf("CNP invalid");
}
return 0;
}
int validateCNP(char cnp[13]) {
char verif[13];
int intVerif[12], intCnp[13];
int i, checksum = 0;
strcpy(&verif[0], "279146358279");
for (i = 0; i<11; i++){
intVerif[i] = (unsigned)verif[i] - 48;
}
for (i=0; i<12; i++) {
intCnp[i] = cnp[i] - 48;
}
for (i=0; i<11; i++) {
checksum += intCnp[i] * intVerif[i];
}
checksum %= 11;
if (checksum == intCnp[12]) {
return 1;
} else {
return 0;
}
}
Sample output
Introduceti CNP-ul:
1650116398203
(lldb)
It also seems that when it converts strings to int arrays, it screws up the last element
Printing description of intVerif:
(int [12]) intVerif = {
[0] = 2
[1] = 7
[2] = 9
[3] = 1
[4] = 4
[5] = 6
[6] = 3
[7] = 5
[8] = 8
[9] = 2
[10] = 7
[11] = 32767
}
Printing description of intCnp:
(int [13]) intCnp = {
[0] = 1
[1] = 6
[2] = 5
[3] = 0
[4] = 1
[5] = 1
[6] = 6
[7] = 3
[8] = 9
[9] = 8
[10] = 2
[11] = 0
[12] = 0
}
Could someone point out what I'm doing wrong, I've tried different approaches, none seemed to work.
Your basic error was already pointed out by MadHatter: Your loops omit the last entry.
Another error is in main: The CNP is 13 characters long, so your cnp array must have at least 14 characters - you have to provide space for the terminating null character '\0'. You should also limit the length of the characters to read in oder to avoid buffer overflow:
scanf("%13s", cnp);
Here, the thirteen means that at most 13 characters (plus the terminating null character) are read.
It is a good idea to check whether your string actually has 13 digits, so that you don't process garbage characters. And you've forgotten to cater for the case where the remainder is 10 - in which case the check digit is 1.
You loop goes from 0 to 10:
for (i = 0; i<11; i++){
intVerif[i] = (unsigned)verif[i] - 48;
}
You are never writing intVerif[11] so it contains garbage.
Similar problem in intCnp[] also.
EDIT : (On OP's Comment)
Looks like your input:"1650116398203" is 13 letters long whereas your cnp array needs one extra space for \0 character. Therfore your input is causing array-out-of-bounds which leads to the undefined behavior.