Changing the base address of an array !!

  • Thread starter karthikbalaguru
  • Start date
K

karthikbalaguru

Hi,

I got an interesting output w.r.t array
manipulation. I have listed the 2 kind
of approaches that were used for
analysis.

Approach 1
-------------------
#include<stdio.h>
int main(void)
{
char a[]="12345\\0";
char *b = "12345\\0";
int i=strlen(a);
int j=strlen(b);
printf("Here i is %d , j is %d\n",i,j);
while(*b!='\0')
{
printf("*b is %c \n",*b++);
}

while(*a!='\0')
{
printf("*a is %c \n",*a++);
}
return 0;
}

For Approach 1, i got the below error message -
error C2105: '++' needs l-value


Approach 2
-----------------
#include<stdio.h>
void incre(char a[]);
int main(void)
{
char a[]="12345\\0";
char *b = "12345\\0";
int i=strlen(a);
int j=strlen(b);
printf("Here i is %d , j is %d\n",i,j);
while(*b!='\0')
{
printf("*b is %c \n",*b++);
}

incre(a);
return 0;
}

void incre(char a[])
{
while(*a!='\0')
{
printf("*a is %c \n",*a++);
}
}

For approach 2, I got the output as below -

Here i is 7 , j is 7
*b is 1
*b is 2
*b is 3
*b is 4
*b is 5
*b is \
*b is 0
*a is 1
*a is 2
*a is 3
*a is 4
*a is 5
*a is \
*a is 0

The manipulation of the base address of the array
shows error if done in main but it works fine if
done in a function.

Is the correct output in Approach 2, is a kind of undefined
behaviour that gives correct output ?

AFAIK, the base address manipulation is not
possible in C language and the compiler does not
allow to do it. But, the output from the approach 2,
seems to convey a different info. Strange !!

Any ideas ?

Thx in advans,
Karthik Balaguru
 
J

James Kuyper

karthikbalaguru said:
Hi,

I got an interesting output w.r.t array
manipulation. I have listed the 2 kind
of approaches that were used for
analysis.

Approach 1
-------------------
#include<stdio.h>
int main(void)
{
char a[]="12345\\0";
char *b = "12345\\0";
int i=strlen(a);
int j=strlen(b);
printf("Here i is %d , j is %d\n",i,j);
while(*b!='\0')
{
printf("*b is %c \n",*b++);
}

while(*a!='\0')
{
printf("*a is %c \n",*a++);

While in most contexts, including this one, the name of an array decays
into a pointer to the first element of that array, it is not a pointer
lvalue. That means that you're not allowed to attempt to modify the
value of that pointer.
}
return 0;
}

For Approach 1, i got the below error message -
error C2105: '++' needs l-value


Approach 2
-----------------
#include<stdio.h>
void incre(char a[]);
int main(void)
{
char a[]="12345\\0";
char *b = "12345\\0";
int i=strlen(a);
int j=strlen(b);
printf("Here i is %d , j is %d\n",i,j);
while(*b!='\0')
{
printf("*b is %c \n",*b++);
}

incre(a);
return 0;
}

void incre(char a[])

While it looks like you've declared 'a' to be an array, that's not
actually the case. When you declare a parameter of a function as if it
were an array, that declaration is automatically converted into a
pointer declaration. In other words, the above declaration is exactly
equivalent to:

void incre(char *a)

Now, when you call eincre() in main() with 'a' as an argument, it is
automatically converted into a pointer to the first element of the array
named 'a'. As before, that pointer is not an lvalue, and it cannot be
changed. However, as a result of the function call, the value of that
non-lvalue pointer is copied into the 'a' which is a pointer parameter
of incre(). That pointer's name does designate a pointer lvalue, and as
a result it is permissible to apply the ++ operator to it, as you do below:
 
B

Barry Schwarz

Hi,

I got an interesting output w.r.t array
manipulation. I have listed the 2 kind
of approaches that were used for
analysis.

You really ought to read the c faq (www.c-faq.com). Many of your
recent discussions are addressed there. This one is covered in
section 6.
 
L

LL

Hi,

I got an interesting output w.r.t array manipulation. I have listed the
2 kind of approaches that were used for
analysis.

Approach 1
-------------------
#include<stdio.h>
int main(void)
{
char a[]="12345\\0";
char *b = "12345\\0";
int i=strlen(a);
int j=strlen(b);
printf("Here i is %d , j is %d\n",i,j); while(*b!='\0')
{
printf("*b is %c \n",*b++);
}

while(*a!='\0')
{
printf("*a is %c \n",*a++);
}
return 0;
}

For Approach 1, i got the below error message - error C2105: '++' needs
l-value


Approach 2
-----------------
#include<stdio.h>
void incre(char a[]);
int main(void)
{
char a[]="12345\\0";
char *b = "12345\\0";
int i=strlen(a);
int j=strlen(b);
printf("Here i is %d , j is %d\n",i,j); while(*b!='\0')
{
printf("*b is %c \n",*b++);
}

incre(a);
return 0;
}

void incre(char a[])
{
while(*a!='\0')
{
printf("*a is %c \n",*a++);
}
}

For approach 2, I got the output as below -

Here i is 7 , j is 7
*b is 1
*b is 2
*b is 3
*b is 4
*b is 5
*b is \
*b is 0
*a is 1
*a is 2
*a is 3
*a is 4
*a is 5
*a is \
*a is 0
Check your output. a[5]=='\' and a[6]=='0' so strlen(a)==7 excluding the
NUL character.

If you don't believe me:

#include <stdio.h>
#include <string.h>

int main() {
char arr[]="abc\\0";

printf("%d", strlen(arr)); // 5

int i=0;
while (arr!='\0') {
printf("%c", arr[i++]); // abc\0
}
}
 
B

Ben Bacarisse

LL said:
#include<stdio.h>
void incre(char a[]);
int main(void)
{
char a[]="12345\\0";
char *b = "12345\\0";
int i=strlen(a);
int j=strlen(b);
printf("Here i is %d , j is %d\n",i,j); while(*b!='\0')
{
printf("*b is %c \n",*b++);
}

incre(a);
return 0;
}

void incre(char a[])
{
while(*a!='\0')
{
printf("*a is %c \n",*a++);
}
}

For approach 2, I got the output as below -

Here i is 7 , j is 7
*b is 1
*b is 2
*b is 3
*b is 4
*b is 5
*b is \
*b is 0
*a is 1
*a is 2
*a is 3
*a is 4
*a is 5
*a is \
*a is 0
Check your output. a[5]=='\' and a[6]=='0' so strlen(a)==7 excluding the
NUL character.

I don't see your point. There is no evidence to suggest that the OP
is unaware that strlen(a)==7 and that a[5]=='\' and a[6]=='0'.
 
J

James Kuyper

Ben said:
LL said:
char a[]="12345\\0"; ....
*a is \
*a is 0
Check your output. a[5]=='\' and a[6]=='0' so strlen(a)==7 excluding the
NUL character.

I don't see your point. There is no evidence to suggest that the OP
is unaware that strlen(a)==7 and that a[5]=='\' and a[6]=='0'.

It strikes me that there is some significant possibility that the OP was
thinking that either a[5]==0 or a[6]==0 It's hard to type \\ rather than
\ by accident, but he might have been copying something he didn't really
understand.
 
K

karthikbalaguru

I got an interesting output w.r.t array manipulation. I have listed the
2 kind of approaches that were used for
analysis.
Approach 1
-------------------
#include<stdio.h>
int main(void)
{
   char a[]="12345\\0";
   char *b = "12345\\0";
   int i=strlen(a);
   int j=strlen(b);
   printf("Here i is %d , j is %d\n",i,j); while(*b!='\0')
   {
           printf("*b is %c \n",*b++);
   }
   while(*a!='\0')
   {
           printf("*a is %c \n",*a++);
   }
                return 0;
}
For Approach 1, i got the below error message - error C2105: '++' needs
l-value
Approach 2
-----------------
#include<stdio.h>
void incre(char a[]);
int main(void)
{
   char a[]="12345\\0";
   char *b = "12345\\0";
   int i=strlen(a);
   int j=strlen(b);
   printf("Here i is %d , j is %d\n",i,j); while(*b!='\0')
   {
           printf("*b is %c \n",*b++);
   }
   incre(a);
                return 0;
}
void incre(char a[])
{
   while(*a!='\0')
   {
           printf("*a is %c \n",*a++);
   }
}
For approach 2, I got the output as below -
Here i is 7 , j is 7
*b is 1
*b is 2
*b is 3
*b is 4
*b is 5
*b is \
*b is 0
*a is 1
*a is 2
*a is 3
*a is 4
*a is 5
*a is \
*a is 0

Check your output. a[5]=='\' and a[6]=='0' so strlen(a)==7 excluding the
NUL character.

If you don't believe me:

#include <stdio.h>
#include <string.h>

int main() {
  char arr[]="abc\\0";

  printf("%d", strlen(arr)); // 5

  int i=0;
  while (arr!='\0') {
    printf("%c", arr[i++]); // abc\0
  }


Yes, I am aware of that output.
I was trying to analyze strlen :):) in that
section of code w.r.t \\ .

Karthik Balaguru
 
K

karthikbalaguru

Ben said:
*a is \
*a is 0
Check your output. a[5]=='\' and a[6]=='0' so strlen(a)==7 excluding the
NUL character.
I don't see your point.  There is no evidence to suggest that the OP
is unaware that strlen(a)==7 and that a[5]=='\' and a[6]=='0'.

It strikes me that there is some significant possibility that the OP was
thinking that either a[5]==0 or a[6]==0 It's hard to type \\ rather than
\ by accident, but he might have been copying something he didn't really
understand.

No. The code was made for the checking of strlen
w.r.t char *b and char a[]. I am aware of those inputs.

Karthik Balaguru
 
K

karthikbalaguru

karthikbalaguru said:
I got an interesting output w.r.t array
manipulation. I have listed the 2 kind
of approaches that were used for
analysis.
Approach 1
-------------------
#include<stdio.h>
int main(void)
{
   char a[]="12345\\0";
   char *b = "12345\\0";
   int i=strlen(a);
   int j=strlen(b);
   printf("Here i is %d , j is %d\n",i,j);
   while(*b!='\0')
   {
           printf("*b is %c \n",*b++);
   }
   while(*a!='\0')
   {
           printf("*a is %c \n",*a++);

While in most contexts, including this one, the name of an array decays
into a pointer to the first element of that array, it is not a pointer
lvalue. That means that you're not allowed to attempt to modify the
value of that pointer.




   }
                return 0;
}
For Approach 1, i got the below error message -
error C2105: '++' needs l-value
Approach 2
-----------------
#include<stdio.h>
void incre(char a[]);
int main(void)
{
   char a[]="12345\\0";
   char *b = "12345\\0";
   int i=strlen(a);
   int j=strlen(b);
   printf("Here i is %d , j is %d\n",i,j);
   while(*b!='\0')
   {
           printf("*b is %c \n",*b++);
   }
   incre(a);
                return 0;
}
void incre(char a[])

While it looks like you've declared 'a' to be an array, that's not
actually the case. When you declare a parameter of a function as if it
were an array, that declaration is automatically converted into a
pointer declaration. In other words, the above declaration is exactly
equivalent to:

void incre(char *a)

Now, when you call eincre() in main() with 'a' as an argument, it is
automatically converted into a pointer to the first element of the array
named 'a'. As before, that pointer is not an lvalue, and it cannot be
changed. However, as a result of the function call, the value of that
non-lvalue pointer is copied into the 'a' which is a pointer parameter
of incre(). That pointer's name does designate a pointer lvalue, and as
a result it is permissible to apply the ++ operator to it, as you do below:


{
   while(*a!='\0')
   {
           printf("*a is %c \n",*a++);
   }
}- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

On similar lines,I got some related info in K&R :-

Consider :-
int a[10];
int *pa;
pa = &a[0];

" There is one difference between an array name and a
pointer that must be kept in mind.
A pointer is a variable, so pa=a and pa++ are legal.
But an array name is not a variable;
constructions like a=pa and a++ are illegal.

When an array name is passed to a function, what is passed
is the location of the initial element. Within the called
function, this argument is a local variable, and so an
array name parameter is a pointer, that is, a variable
containing an address. "

Since it is a variable inside that function, incrementation
is legal and that will not have any effect on the character
string in the main that called that function.

Karthik Balaguru
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top