how array is working without declare it in this program - c

#include <stdio.h>
void main()
{
char *s= "hello";
char *p = s;
printf("%c\t%c", p[0], s[1]);
}
output of this program is : h e
Can anyone please explain how this program is working? I'm relatively new to c..

p[0] is identical to *(p+0) , similarly goes for s[1] . [] always operates on a pointer and is same for arrays and pointers.
Note - There is no array declared in your program.

Please note the following facts first( They are neutral to programming LANGUAGE )
Any pointer has/ takes memory equals to size of your systems data bus
even void* takes size equals size of your systems data bus
Now size of data bus is size of processors data fetching/manipulating capacity, you might heard 32 Bit processor, 64 Bit processor
Finally processors data fetching/manipulating capacity equals size of your int, that's why we use following code to calculate Architecture of CPU
#include<stdio.h>
int main(){
if(sizeof(int)==2) {
printf("\n 16 Bit Architecture, may be using DOS & Turbo C++ IDE");
}else if(sizeof(int)==4) {
printf("\n 32 Bit Architecture");
}else {
printf("\n 64 Bit Architecture");
}
return 0;
}

Related

Segmentation fault error array in c [duplicate]

This question already has answers here:
Getting a stack overflow exception when declaring a large array
(8 answers)
Closed 4 years ago.
I want to write a program in which I want to initialize integer array of size 987654321 for storing values of 1 and 0 only,
here is my program
#include <stdio.h>
#include <stdlib.h>
int main(){
int x,y,z;
int limit = 987654321;
int arr[limit];
for (x = 0;x < limit;x++){
printf("%d \n",arr[x]);
}
return 0;
}
but it gives segmentation fault
987654321 is certainly too big for a local variable.
If you need a dynamically sized array of that size you need to use malloc like:
int limit = 987654321;
int *arr = malloc(limit * sizeof(*arr));
if (arr == NULL)
{
... display error message and quit
}
...
free(arr); // free it once you're dont with the array
BTW are you aware that your array uses roughly 4 gigabytes of memory assuming the size of int is 4 on your platform?
Since you want to store values of 1 and 0 only, and these values require only one bit, you can use a bit array instead of an integer array.
The size of int is 4 bytes (32 bits) usually, so you can reduce the memory required by a factor of 32.
So instead of about 4 GB, you will only need about 128 MB of memory. Resources on how to implement a bit array can be found online. One such implementation is here.

compilation error in C pointer working in 32 bits, not in 64 bits

I am trying to compile a c program in 64 bits. It is already working in 32 bits for several years and used by some clients.
Example of code working in 32 bits :
#include <stdio.h>
int main() {
char* rcfilename ;
char* vhome ;
char* script = "/script/main.tcl" ;
vhome = (char *)getenv("VHOME");
rcfilename = (char *) malloc(strlen(vhome) + strlen(script) + 1) ;
strcpy(rcfilename, vhome) ;
return 0;
}
in Compil in 64 bits i have an error:
conversion between a pointer and an integer of different size
and a segmentation fault in execution.
I have no experience in pointer in c, so i prefer to ask for help !
As mentionned in the comments, you should:
include the proper headers (stdlib.h and string.h)
check for the value return, in particular the getenv call:
if (!(vhome = (char *)getenv("VHOME"))){
fprintf(stderr, "getenv(\"VHOME\") returned NULL\n");
return -1;
}

Why do I get these memory addresses?

I was wondering why I get these memory addresses in this simple program.
#include <stdio.h>
int main() {
char *a = "buffera";
char *b = "bufferbb";
printf("%p %p\n", a, b);
return 0;
}
Output I get is.
00403064 0040306C
Supposedly each character occupies one byte in memory (two hex numbers), then if the string a occupy 7 + 1 = 8 bytes in memory and the address of a starts at 0x00403064, then according to me it should end at 0x00403079 and not at 0x0040306B.
0043064 + 8 = 0040306C; I don't know where you get 00403079 from.
0x00403064 + 0x8 == 0x0040306C
Note that these numbers are in hexadecimal.
But either way, while these strings can't overlap, they don't need to be placed anywhere near each other in memory.

comparing two arrays of integers in c acts odd

Here is part of my code , I read some fields of a kernel data structure and compare it with an array. but oddly I see that when I print contents of array orig_poolinfo the first element is 103 though it is actually 128.
int get_poolinfo_fields(vmi_instance_t vmi)
{
int orig_poolinfo[]={128,103,76,51,25,1,32,26,20,14,7,1};
uint64_t poolinfo_table_addr = 0xffffffff81ca4fc0;//kernel 3.11
int poolinfo_table;
int i;
//for( i=0;i<12;i++)
// printf("poolinfo_table=%d %d\n",i,orig_poolinfo[i]);
for( i=0;i<12;i++)
{
vmi_read_64_va(vmi,poolinfo_table_addr, 0, &poolinfo_table);
printf("poolinfo_table=%d orig_poolinfo[%d]=%d\n",poolinfo_table,i,orig_poolinfo[i]);
if(poolinfo_table != orig_poolinfo[i])
printf("hi\n");//return(1);
poolinfo_table_addr = poolinfo_table_addr + 0x4;
}
return(0);
}
and this is the output:
poolinfo_table=128 orig_poolinfo[0]=103
hi
poolinfo_table=103 orig_poolinfo[1]=103
poolinfo_table=76 orig_poolinfo[2]=76
poolinfo_table=51 orig_poolinfo[3]=51
poolinfo_table=25 orig_poolinfo[4]=25
poolinfo_table=1 orig_poolinfo[5]=1
poolinfo_table=32 orig_poolinfo[6]=32
poolinfo_table=26 orig_poolinfo[7]=26
poolinfo_table=20 orig_poolinfo[8]=20
poolinfo_table=14 orig_poolinfo[9]=14
poolinfo_table=7 orig_poolinfo[10]=7
poolinfo_table=1 orig_poolinfo[11]=1
You are mixing two different types int and uint64_t. Their sizes might not be the same.
By using vmi_read_64_va() you copy 8 bytes. If sizeof( int ) is 4 on your system you get undefined behavior. This means anything can happen and your program is not behaving correctly.
Use functions appropriate to your type size and don't mix types.

How many GB can malloc allocate for your program

I used the following code to find it out but I always get 1 as the answer. is there something wrong. Thanks
#include <stdio.h>
#include <stdlib.h>
int main(){
int mult = 0;
int chk =8;
do{
mult+=1;
int *p = (int*)malloc(1024*1024*1024*mult);
if(p==0){
chk =0;
}else{
free(p);
}
}while(chk !=0);
mult = mult -1;
printf("The number of gigs allocated is : %d\n",mult);
return 0;
}
Just to help, I have a 64 bit system with both windows and linux installed. Thus, is the above logic correct even though I am getting just 1 gb as the answer on a 64 bit system?
If it is a 32-bit OS, then it is not surprising that the largest contiguous block would be 1GB (or somewhere between that and 2GB). On a 64-bit OS, larger blocks would be possible.
If you change your code to allocate smaller individual pieces, you will likely be able to allocate more than 1GB total.
These questions might help you a bit: How much memory was actually allocated from heap for an object? and How do I find out how much free memory is left in GNU C++ on Linux
int main(void){
int MB = 0;
while(malloc(1<<30)){
++MB;
}
printf("The number of gigs allocated is : %d\n",MB);
return EXIT_SUCCESS;
}

Resources