I am having problems with a c pointer exercise.
I understand how a pointer works but this exercise is confusing me.
#include <stdio.h>
char* c[] =
{
"he dast ga",
"lllt dumm",
"C i",
"dar nich"
};
char** cp[] = { c + 3, c + 2, c + 1, c };
char*** cpp = cp;
int main(void)
{
printf("%s", **++cpp);
printf("%s", *-- * ++cpp + 5);
printf("%s", cpp[-2][0] + 2);
printf("%s\n", *(cpp[1] + 1) + 3);
getchar();
}
Could someone please explain this to me?
I thought that the pointer cpp would be incremented and point to the value c + 2. I coincidentally got the right result but it didn't work for the second pointer. Then I looked up that the ++ is not an increment but that the first value of the array gets cut of so that I have a new array with the values { c + 2, c + 1, c }. But I still don't know how I get "c i" as a result from this.
Let's keep track of where everything is pointing as we go through:
Initially, we have this:
c: { "he dast ga", "lllt dumm", "C i", "dar nich" }
cp: { c + 3, c + 2, c + 1, c }
cpp: cp
printf("%s", **++cpp); increments cpp, so we now have cpp: cp + 1.
Then, dereference it twice: *cpp: c + 2, **cpp: "C i".
So we print out C i. And our variables now look like this:
c: { "he dast ga", "lllt dumm", "C i", "dar nich" }
cp: { c + 3, c + 2, c + 1, c }
cpp: cp + 1
Note that cpp has changed.
printf("%s", *-- * ++cpp + 5); is next.
First we increment cpp again: cpp: cp + 2. Then dereference it: *cpp: c + 1. Then decrement, giving us c and updating the appropriate element of cp. Then, dereference: *c: "he dast ga", then add 5: st ga.
So we print out st ga, and our variables look as follows:
c: { "he dast ga", "lllt dumm", "C i", "dar nich" }
cp: { c + 3, c + 2, c, c }
cpp: cp + 2
Note the two updates, to cp[2] and cpp.
We don't update any more variables from this point on, so I will not show the variables anymore, just what happens as we evaluate.
printf("%s", cpp[-2][0] + 2);
cpp[-2][0] + 2
(cp + 2)[-2][0] + 2
cp[0][0] + 2
(c + 3)[0] + 2
c[3] + 2
"dar nich" + 2
"r nich"
So we print out r nich.
Finally, printf("%s\n", *(cpp[1] + 1) + 3);:
*(cpp[1] + 1) + 3
*(*(cpp + 1) + 1) + 3
*(*(cp + 2 + 1) + 1) + 3
*(*(cp + 3) + 1) + 3
*(c + 1) + 3
"lllt dumm" + 3
"t dumm"
So we print out t dumm.
Putting everything together, we should print out C ist gar nicht dumm (Roughly: "C is not so dumb after all" I believe).
Related
I am trying to create an array of pointers to store 6 array's with varying amount of dimensions and types. I use this in a much bigger program, I tried to make the easiest/smallest possible representation of the problem, just bare in mind that in the actual program there are a lot more variables.
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MCD 5
const uint64_t layer_s[] = { /* The start of each layer */
0,
1,
1 + 4,
1 + 4 + pow(4, 2),
1 + 4 + pow(4, 2) + pow(4, 3),
1 + 4 + pow(4, 2) + pow(4, 3) + pow(4, 4),
1 + 4 + pow(4, 2) + pow(4, 3) + pow(4, 4) + pow(4, 5)
};
const uint64_t l_size[] = { /* Size of each layer */
1, 4,
pow(4, 2), pow(4, 3),
pow(4, 4), pow(4, 5)
};
void
func(void *a_p, uint_fast32_t obj_pos, uint_fast32_t nrn_pos,
uint_fast8_t l_shifted, uint_fast8_t l_remaining)
{
void *(*a) = a_p; /* Array array's */
uint32_t(*neuron_a)[layer_s[MCD + 1]] = a[0]; // Neuron array [Objects][Neurons]
uint16_t(*str_a)[layer_s[MCD + 1]] = a[1]; // Strength array [Objects][Neurons]
uint8_t(*TS_a)[layer_s[MCD + 1]] = a[2]; // Total score array [Objects][Neurons]
int8_t(*prox_a) = a[3]; // Proximity array [Objects]
float (*prox_ang_a) = a[4]; // Proximity angle array [Objects]
void *(*prox_obj_a) = a[5]; // Proximity object array Objects]
uint_fast8_t i = 0;
printf
("Input variables: [%d][%d] layer_shift: %d layer remaining: %d\n",
obj_pos, nrn_pos, l_shifted, l_remaining);
while (1) { /* Shift every layer down by l_shifted layers */
printf("memmove(%d, [%d][%d], %d)\n", layer_s[l_remaining - i],
obj_pos, nrn_pos, l_size[l_remaining - i]);
memmove(a[0] +
layer_s[l_remaining - i] * layer_s[MCD +
1] *
sizeof(uint32_t), &neuron_a[obj_pos][nrn_pos],
l_size[l_remaining - i] * layer_s[MCD +
1] *
sizeof(uint32_t));
memmove(a[1] +
layer_s[l_remaining - i] * layer_s[MCD +
1] *
sizeof(uint16_t), &str_a[obj_pos][nrn_pos],
l_size[l_remaining - i] * layer_s[MCD +
1] *
sizeof(uint16_t));
memmove(a[2] +
layer_s[l_remaining - i] * layer_s[MCD +
1] * sizeof(uint8_t),
&TS_a[obj_pos][nrn_pos],
l_size[l_remaining - i] * layer_s[MCD +
1] * sizeof(uint8_t));
memmove(a[3] + layer_s[l_remaining - i] * sizeof(int8_t),
&prox_a[obj_pos],
l_size[l_remaining - i] * sizeof(int8_t));
memmove(a[4] + layer_s[l_remaining - i] * sizeof(float),
&prox_ang_a[obj_pos],
l_size[l_remaining - i] * sizeof(float));
memmove(a[5] + layer_s[l_remaining - i] * sizeof(void *),
&prox_obj_a[obj_pos],
l_size[l_remaining - i] * sizeof(void *));
if (i++, i <= l_remaining) {
obj_pos = round((double)(obj_pos - layer_s[i - 1]) / 4); /* Go 1 layer lower */
nrn_pos = round((double)(nrn_pos - layer_s[i - 1]) / 4);
} else
break;
}
}
int main()
{
void *(*a) = malloc(6 * sizeof *a); /* Array of array's */
a[0] = malloc(layer_s[MCD + 1] * layer_s[MCD + 1] * sizeof(uint32_t));
a[1] = malloc(layer_s[MCD + 1] * layer_s[MCD + 1] * sizeof(uint16_t));
a[2] = malloc(layer_s[MCD + 1] * layer_s[MCD + 1] * sizeof(uint8_t));
a[3] = malloc(layer_s[MCD + 1] * sizeof(int8_t));
a[4] = malloc(layer_s[MCD + 1] * sizeof(float));
a[5] = malloc(layer_s[MCD + 1] * sizeof(void *));
/* Set array's to 0 */
memset(a[1], 0, layer_s[MCD + 1] * layer_s[MCD + 1] * sizeof(uint16_t));
memset(a[5], 0, layer_s[MCD + 1] * sizeof(void *));
func(a, 1, 1, 1, 0);
/* free array's */
return 0;
}
The output it gives:
Input variables: [1][1] layer_shift: 1 layer remaining: 0
memmove(0, [0][1], 1)
The expected output:
Input variables: [1][1] layer_shift: 1 layer remaining: 0
memmove(0, [1][1], 1)
Notice how the obj_pos changes from 1 to 0 where no code besides print functions are executed, I would expect obj_pos to be 1 in the second print function too.
EDIT: I've ran this program on a different computer too, here the output is correct, but the memory does still get corrupted, just a few bytes later.
I believe earlier in the programs runtime the memory heap gets corrupted, but I failed to find where. Does someone understand what causes obj_pos to change value between the two print functions?
EDIT 2: I am using 32 bit GCC, with an x64 CPU with 64 bit, could this cause issues between the sizes of the pointers?
Answer:
The problem was that pointer (void*) were 4 bytes in GCC and my OS was using 8 bytes per pointer, this caused the memory alignment for the array of void* to be cause heap corruption.
This is really a shame since with mingw-w32 its specified that its 32 bit GCC compiler works on 64 bit operating systems.
You have set MCD to 5 but you are adding one to it when accessing layer_s. Layer_s only has 6 entries 0..5 so the value at offset 6 is undefined. This would lead to the malloc’ed memory being of unknown size and you will probably corrupt the heap when you memset your arrays to 0.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a , b ,c ;
printf("Enter values for a and b: ");
scanf("%d%d",&a,&b);
a = a + b-- ;
if (a<b){
c = -1;
printf("\n\t%d %d %d\n\n",a,b,c);
}
else {
c = 0;
printf("\n\t%d %d %d\n\n",a,b,c);
}
}
Lets assume the value of the input for a and b are 2 (for both of them).
I studied the above program, but when it comes to the output it will be 4 1 0, a=4,b=1,c=0.
But, the calculation part above said that a=a+b-1 which will be the value of a is 3, now the new value of a is 3. But for b the value is still 2 because we didn't assign a new value to it.
I am very confused about the output.
There is a difference between a+1, a++ and ++a. Details here.
Therefore, when you say
a = a + b--;
You are actually saying
a = a + b;
b = b - 1;
If you say
a = a + --b;
It becomes
b = b - 1;
a = a + b;
And if you say
a = a + (b-1)
It does what you think: a = a + b - 1. The value of b doesn't change afterwards.
At the beginning, a and b are both 2
Then, you execute a = a + b--;.
The decrement operator is located after the b, so it evaluates to:
a=a+b;
b=b-1;
After this, a will be 4 and b will be 1.
a is not smaller than b, so c will be 0.
Note:
If it would be a = a + --b, it would evaluate to
b=b-1;
a=a+b;
Because the -- is executed at the beginning of the evaluation.
I'm a little new to programming, I'm trying to write a program to solve quadratic equation, here's my code:
#include <stdio.h>
#include <math.h>
void main (){
int a, b, c, delta;
float root1, root2;
delta = ( b * b ) - ( 4 * a * c );
printf("enter a, b, c, in such syntax ax^2 + bx + c:\n");
scanf("%d%d%d", &a, &b, &c);
printf("You mean %dx^2 + %dx + %d, delta=%f\n\n", a, b, c, delta);
if ( delta < 0 )
printf("The equation has no roots.\n");
if ( delta == 0 ){
root1 = -b / (2*a);
printf("The equaion has one root: %d\n", root1);
}
if ( delta > 0 ){
root1 = (-b + sqrt(delta)) / (2*a);
root2 = (-b - sqrt(delta)) / (2*a);
printf("root 1 = %f\nroot 2 = %f\n", root1, root2);
}
}
It's compiled without error, the problem is each time I run it, with same input, I get different answers!
$ ./qe
enter a, b, c, in such syntax ax^2 + bx + c:
2
4
2
You mean 2x^2 + 4x + 8, delta=0.000000
The equation has no roots.
$ ./qe
enter a, b, c, in such syntax ax^2 + bx + c:
2
4
2
You mean 2x^2 + 4x + 8, delta=0.000000
root 1 = 6543.122070
root 2 = -6545.122070
$ ./qe
enter a, b, c, in such syntax ax^2 + bx + c:
2
4
2
You mean 2x^2 + 4x + 8, delta=0.000000
root 1 = 8342.037109
root 2 = -8344.037109
$ ./qe
enter a, b, c, in such syntax ax^2 + bx + c:
2
4
2
You mean 2x^2 + 4x + 8, delta=0.000000
The equation has no roots.
.
.
I'm so confused. Whats the problem? My gcc version: 6.3.1 20170306 (GCC)
how should I fix this?
Thanx.
TL;DR Your code causes undefined behavior.
To elaborate, in the case
delta = ( b * b ) - ( 4 * a * c );
a, b, c are used uninitialized. They
can have trap representation
do not have their address taken.
So, this invoke UB.
You need to
first check for the success of scanf() call
move the calculation of delta after the successful scanning for values for the involved operands.
Also, to add, for a hosted environment, the conforming signature for main() would be int main(void), not void main ()
int a[] = {10, 15, 20, 25};
int b[] = {50, 60, 70, 80, 90};
int *x[] = {a, b};
int *y[] = {a + 2, b + 3};
int *p;
int *q;
int **r;
p = a;
q = y[1];
r = &q;
*p = &p[3] - y[0];
r[0][1] = **r - y[0][1];
What are the contents of a and b at the end?
I figured out that *p is a[0], and &p[3] - y[0] is just 3 - 2, so a[0] = 3 - 2 = 1. Therefore, a[] = {1, 10, 15, 20} (correct me if I am wrong), but b[] is where I get lost. I have no idea how the last line of the code works. No idea on what r[0][1] refers to, so getting the contents for b[] is confusing. P.S. this is for C.
Remember that the identity *(p + k) == p[k] (or p + x == &p[k]) means that you can always rewrite dereferencing as indexing and vice-versa, so if an expression is confusing you can try a different form and see if it makes more sense.
I personally find indexing easier to reason about:
Since r = &q, both r[0] and *r are the same as q:
q[1] = *q - y[0][1];
or
q[1] = q[0] - y[0][1];
q is y[1] gives:
y[1][1] = y[1][0] - y[0][1];
y[0]is a + 2 and y[1] is b + 3:
(b + 3)[1] = (b + 3)[0] - (a + 2)[1];
which is
*(b + 3 + 1) = *(b + 3 + 0) - *(a + 2 + 1);
which is
*(b + 4) = *(b + 3) - *(a + 3);
which is
b[4] = b[3] - a[3];
that is,
b[4] = 80 - 25;
The line int **r; declares a pointer to an int *. In other words, r is a pointer to a pointer to an int. If you recall that the syntax x[y] is equivalent to *(x + y), you might get an idea for what r[0][1] does.
r[0][1] --> *((*(r + 0)) + 1)
Keeping in mind that r[0][1] is on the LHS of the assignment operator, you are storing to that memory location.
Recently I've been checking out the CMSIS DSP complex math functions library and I've seen something I cannot fully comprehend, thus my first post on SO.
What I'm unable to grasp is how the he11 can the complex dot product function yeild a proper result? The function may be found here: Complex Dot Product
As far as I'm concerned the part
for(n=0; n<numSamples; n++) {
realResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+0] - pSrcA[(2*n)+1]*pSrcB[(2*n)+1];
imagResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+1] + pSrcA[(2*n)+1]*pSrcB[(2*n)+0];
}
is A-okay, but how's that:
/* CReal = A[0]* B[0] + A[2]* B[2] + A[4]* B[4] + .....+ A[numSamples-2]* B[numSamples-2] */
real_sum += (*pSrcA++) * (*pSrcB++);
/* CImag = A[1]* B[1] + A[3]* B[3] + A[5]* B[5] + .....+ A[numSamples-1]* B[numSamples-1] */
imag_sum += (*pSrcA++) * (*pSrcB++);
supposed to work, since it misses the product of real*imag parts of the samples?
It might - and most probably is - a really dumb question, but somehow I simply cannot see it working.
That looks simply wrong, and the implementation doesn't match the description.
Suppose we have z = x + i*y and w = u + i*v with x, y, u, v real. Then
z*w = (x + i*y)*(u + i*v) = (x*u - y*v) + i*(x*v + y*u)
and
z*conjugate(w) = (x + i*y)*(u - i*v) = (x*u + y*v) + i*(y*u - x*v)
So with the loop
while(blkCnt > 0u)
{
/* CReal = A[0]* B[0] + A[2]* B[2] + A[4]* B[4] + .....+ A[numSamples-2]* B[numSamples-2] */
real_sum += (*pSrcA++) * (*pSrcB++);
/* CImag = A[1]* B[1] + A[3]* B[3] + A[5]* B[5] + .....+ A[numSamples-1]* B[numSamples-1] */
imag_sum += (*pSrcA++) * (*pSrcB++);
/* Decrement the loop counter */
blkCnt--;
}
you will get real_sum + imag_sum = Real part of hermitian inner product finally.
Neither real_sum nor imag_sum is in any simple way related to the real/imaginary part of the inner product nor the bilinear product.