Pointers in C, theoretical aspect - c

I have programming exam soon, and I still can't understand some things, could you guys help me?
Basically, we got:
char *nap[]= {"Reklamacja","Perspektywa","Reinkarnacja","Hermengilda","Audytorium","Mineralogia","Frustracja"}
Those are bunch of words in Polish language, but they doesn't matter at all.
So moving on, we have:
Size of char type on this PC : 1
Size of long type on this PC : 4
Address of beginning nap array (char type): 0x22ff20
Address of R letter in word "Reklamacja": 0x47575d,
Address of P letter in word "Perspektywa": 0x475768,
Address of R letter in word "Reinkarnacja": 0x475774,
Address of H letter in word "Hermengilda": 0x475781,
Address of A letter in word "Audytorium": 0x47578e,
Address of M letter in word "Mineralogia": 0x475799,
Address of F letter in word "Frustracja": 0x4757a5
The question is: what is the effect of the following line of code?
printf("%#lx", nap+5);
The correct answer is: 0x22ff34
Why is it like so and not like 0x22ff20 + 5 which is 0x22ff25?

The answer is the same for any typed pointer value in C, and uses a language feature called pointer arithmetic.
What is the byte-width of the element type, including padding if a struct or union type?
Multiply by the index N you're using
Add to the base address of the array.
The result should be the address of the N'th element in the sequence. Note you cannot portably do this with void*, and any cast you perform on the pointer prior to performing the operation will affect the outcome.
In your case, the element type of your array is char *. Assuming sizeof(char*) == 4 on your platform then
4 bytes
4 * 5 = 20 bytes (0x14)
0x22ff20 + 0x14 = 0x22ff34
Remember, an array expresses as pointer-to-type with a value of the array base-address when used in the above calculation. It may seem trivial, but that is routinely the part of this that is missed.
Best of luck

nap is a pointer to the first item of the array: nap == &(nap[0]).
nap+5 is a pointer to the sixth item of the array: nap+5 == &(nap[5]).
Each item of your array is 4 bytes long (test for sizeof(char *)), so the numerical value of nap+5 is a numerical value of nap plus 5 times 4:
0x22ff20 + 4*5 = 0x22ff20 + 0x14 = 0x22ff34

Your nap variable is declared as a pointer to an array of strings. So when you are using nap+5 you are really moving the pointer 5 elements down the array (which will point to Mineralogia). In order to retrieve the result that you were expecting, you will have to cast the pointer so it will point to the first string, then add 5 to it to move the pointer 5 characters down. Here is a test application that I wrote up to demonstrate this (my code usually explains better than I can verbally lol):
#include <stdio.h>
int main()
{
char* nap[] = {"Reklamacja","Perspektywa","Reinkarnacja","Hermengilda","Audytorium","Mineralogia","Frustracja"};
//Returns the beginning address of nap
printf("%#lx\r\n", nap);
//Returns the sixth string in nap (aka nap[5] since arrays are 0-based index)
//and the address
printf("%s %#lx\r\n", *(nap+5), nap+5);
//Returns the first string in the array (aka nap[0]) and the address
printf("%s %#lx\r\n", *nap, *nap);
//Returns the 1st string in the array starting at the 6th letter and the address
printf("%s %#lx\r\n", *nap+5, *nap+5);
return 0;
}
Also remember that a char is 4 bytes so the last printf statement moved the pointer 20 bytes down the string.

Related

PostgreSQL PqGetValue char to integer in c programming

I have a little problem with PostgreSQL results and integer in C language. So I have a simple table with this structure :
ID(pk int) | name (text) | values (int)
1 | apple | 100
2 | banana | 9
I use this code :
PGconn *conn = PQconnectdb("user=un password=pw dbname=db hostaddr=1.2.3.4 port=5432");
res = PQexec(conn, "SELECT * FROM fruits WHERE name='banana'");
int *banan_count;
banana_count = (int)PQgetvalue(res, 0, 2);
printf ("Banana values : %u\n", banana_count);
PQclear(res);
do_exit(conn);
The problem is that my results isn't '9' when I try print out with 'banana_count', but when I print out 'PQgetvalue(res, 0, 2)' then I got '9', so I think I have a conversion problem, but I can't find a solution. So my question is that how can I convert 'PQgetvalue(res, 0, 2)' to integer variable in C proramming language? (I use Ubuntu 18.04 and for compile my fruits.c with gcc).
Thank you for the supports and helps.
In C, text is technically an array of chars, followed with a null-term. Roughly, array is a pointer to allocated memory of known size (syntax may vary widely). So let's see the code.
PGconn *conn = PQconnectdb("user=un password=pw dbname=db hostaddr=1.2.3.4 port=5432"); //No doubts. It's your professional area.
res = PQexec(conn, "SELECT * FROM fruits WHERE name='banana'"); //same thing.
//int *banan_count; //Aside the typo (banana_count), you don't need a pointer to int! PQgetvalue returns a pointer to char (roughly equal to array of chars, roughly equal to text, you'll learn differences later). This array keeps ONE int value in text form.
int banana_count_2; //That's what you need: a single int value. Not a pointer.
//banana_count = (int)PQgetvalue(res, 0, 2); //Wrong: you take the pointer to char, convert it few times and assign to your int* pointer. Pointer becomes technically valid, but it points to first group of characters, reading them as an integer value (probably char1 + char2*256 + char3*65536 ... depending on your platform). Of course, actual integers are not represented in text form in computer memory, so you get an absurdly huge value (even '0' character has code 48).
banana_count_2 = atoi(PQgetvalue(res,0,2)); //PQgetvalue allocates memory by itself, so the char* it returns points to a valid, allocated memory area. We can say it's an array filled with null-terminated text line, and give this line to atoi();
printf ("Banana values : %u\n", banana_count_2);
PQclear(res); //Good thing you didn't forget to unallocate the char array!
do_exit(conn);

sizeof dynamic array is not correct [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 7 years ago.
In array there are four element so it size should be 4bit*4 = 16. (An int data type take 4 bit in my system to store the value.) But when i ran this code i only got 8 bit as the size of dynamicArray.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
//Dynamic arrays save memory by creating a pointer that stores
//the beginning of the array
int *dynamicArray = malloc(20 * sizeof(int));
*dynamicArray = 10;
printf("Address %x stores value %d\n", dynamicArray, *dynamicArray);
dynamicArray[1] = 20;
printf("dynamicArray[1] stores value %d\n", dynamicArray[1]);
dynamicArray[2] = 45;
printf("dynamicArray[2] stores value %d\n", dynamicArray[2]);
dynamicArray[3] = 34;
printf("dynamicArray[3] stores value %d\n", dynamicArray[3]);
printf("The size of dynamicArray is %d\n", sizeof(dynamicArray));
// Release unused memory:
free(dynamicArray);
return EXIT_SUCCESS;
}
Here is the image of output.
Also suggest me website for C to check the in-built function properties or to know about them more.
Thank you.
You don’t have an array; you have a pointer.
The size of the pointer is measured in bytes, not bits.
sizeof is evaluated at compile time and is constant for any given expression or type. It does not depend on the number of “filled” elements in an array (or pointer to some space that holds those elements, for that matter).
Your expression is equivalent to sizeof(int*), and pointers are 8 bytes in your environment.
I ran your code on my 32-bit computer and the value of sizeof(dynamicArray) does report 4. I bet your computer is 64-bits which is why the value is 8 instead.
Take a look at: http://www.viva64.com/en/a/0004/ and look for the table titled "Table N2. 32-bit and 64-bit data models.". That would help explain why some systems report 4 and some report 8 for the value for sizeof(dynamicArray).

C: attempting to invert the order of 10 words in a matrix

I have a matrix of 10 lines and 20 columns; so I ask the user to enter with 10 words and put each word in one line of the matrix. In the next step, I must create another matrix (with the same proportions) in a way that the first word of the first matrix is at the last word of the second matrix, the second word of the first matrix is at the penultimate word of the second matrix, and so on.
But I'm getting some problems with the code:
#include <stdio.h>
int main() {
char str[10][20], str2[10][20];
int i, j=9;
/* filling the first matrix */
for(i =0;i <10;i++){
scanf("%s",str[i]);
}
/* copying to the second matrix in an inverted order */
for (i=0;i<10;i++, j--){
str2[i] = str[j];
}
return 0;
}
It returns the following error: incompatyble types when assigning to type 'char[20]'from type 'char*'
at the line:
"str2[i] = str[j]"
Ideas?
If you say
char str2[10][20];
then str2 is a two dimensional array of chars, specifically it is 200 chars arranged in 10 rows of 20 chars.
If you declare str2 that way, then str2[i] is equivalent to a pointer to a char, but it is not an assignable pointer. In other words, that pointer can only be used on the right side of an equals sign, not the left side of an equals sign.
If you want an array of pointers, you must declare the array as
char *str2[10];
In this case, str2 is a one dimensional array of pointers-to-char. Specifically it is an array of 10 pointers (which will occupy 40 bytes of memory on a 32-bit machine).
So there's the distinction, char str2[10][20] occupies 200 bytes of memory and has no assignable pointers, whereas char *str2[10] occupies 40 bytes of memory and has 10 assignable pointers.
In c you cannot write(assign) to arrays in their entirety, like the commentor said you should use strcopy (memcpy if its not strings) for this purpose.

int* vector accepts only the first given value

I'm experiencing some troubles with my code written in C. It's all about an int * vector intially declared and dynamically allocated but when it comes to filling it with data it stuck on the first element and won't increment the counter to fill the rest of the vector
my header file : instance.h
struct pbCoupe
{
int tailleBarre;
int nbTaillesDem;
int nbTotPcs;
int * taille;
int * nbDem;
};
my code : coupe.c
pb->taille = (int*) malloc (pb->nbTaillesDem * sizeof(int));
pb->nbDem = (int*) malloc (pb->nbTaillesDem * sizeof(int));
while (i < pb->nbTaillesDem)
{
fscanf_s(instanceFile,"%s",data,sizeof(data));
pb->taille[i] = atoi(data); //<-- here is the problem !! it only accept the first value and ignore all the rest
printf("%s\n",data);
fscanf_s(instanceFile,"%s",data,sizeof(data));
pb->nbDem[i] = atoi(data); //<-- the same problem here too !!
printf("%s\n",data);
i++;
}
Your interpretation of sizeof is wrong, since data is the buffer that the string is being parsed into.
It returns the size of the the variable, not the size of the the what the variable (or namely a pointer) points to
Strings in C are all pointer to the size would be 4 bytes on a 32-bit system, 8 on a 64-bit.
Since it prints all the number it reading more numbers that intended with each loop iteration 4 bytes = 4 characters, atoi on parses the first integer and returns,
EDIT: If it is a buffer array, sizeof returns the size of the array.
You need to make sure you are only reading in a single number per iteration of the loop to solve this issue.
If you don't care for the literal string, best thing you can do is use:
fscanf(instanceFile, "%d", ((pb->taille) + i)));
//and store the integer into the index right away
//last param same as &pb->taille[i]

Subtracting two strings in C

Well , I was actually looking at strcmp() , was confused about its working . Anyways I wrote this code
#include <stdio.h>
main()
{
char a[5] = "ggod";
char b[5] = "ggod";
int c = 0;
c = b - a;
printf("%d value", c);
}
and I get the output as
16
Can anyone explain Why is it 16 ?
What you have subtracted there are not two strings, but two char *. c holds the memory address difference between a and b. This can be pretty much anything arbitrary. Here it just means that you have 16 bytes space between the start of the first string and the start of the second one on your stack.
c = b - a;
This is pointer arithmetic. The array names it self points to starting address of array. c hold the difference between two locations which are pointed by b and a.
When you print those values with %p you will get to know in your case
if you print the values looks like this a==0x7fff042f3710 b==0x7fff042f3720
c= b-a ==>c=0x7fff042f3720-0x7fff042f3710=>c=0x10 //indecimal the value is 16
Try printing those
printf("%p %p\n",a,b);
c=b-a;
if you change size of array difference would be changed
char a[120]="ggod";
char b[5]="ggod";
b is an array object
a is also an array object
an array object is a static address to an array.
so b-a is adifference between 2 addresses and not between the 2 strings "ggod"-"ggod"
If you want to compare between 2 string you can use strcmp()
strcmp() will return 0 if the 2 strings are the same and non 0 value if the 2 strings are different
here after an example of using strcmp()

Resources