Pointers Homework

Pages: 1234
gratrstone: Stop posting. Seriously, GTFO.

Everyone else:
New questions (answers to the previous round below):
4. What's the difference between char string[]="Hello, World!\n"; and char *string="Hello, World!\n";?
5. Is there some way to tell the size of the array pointed to by a pointer without terminating it with a special element or remembering its size?
6. Write a short program that uses the standard qsort() to sort an array of integers. The array should be as long as the user wishes and filled with random data. After sorting, verify that it was sorted correctly.

If you can do #6, you more or less know about pointers as much as there is to know.




Answers:

2. There's an implicit conversion to char * on line 1. String literals are pointers to constants. The compiler allows this conversion for compatibility with C. Line 2 will produce an error (probably) because the program is writing to read-only memory.

3. The value of x is undefined. Casting a [pointer to constant] to a [pointer to variable] and then writing to that location has undefined behavior.
http://www.cplusplus.com/forum/general/17155/#msg85903
Last edited on
4. Dunno I asked the same question last week it was never answered, I'm going to guess the former should be: char* string="Hello, World!\n"; to be equal to the first.

5. yes. ;p
Last edited on
4. Well, of course if you change one into the other they will be the same. :P
5. Heh, okay. How?
closed account (jwC5fSEw)
1
2
3
4
5
int strlen(const char *s){
    char *p=s;
    for (;*p;p++);
    return p-s;
}


Okay, I don't think I understand this, so let me see: a pointer p points the value of s. Then, in the for loop, for every letter in p, its address is incremented (is that right?). Then, the address of s is subtracted from the address of p, which gives the size. How wrong am I?
Shadow Addict: That's entirely correct.

The beauty of pointer arithmetic is that you can change the pointed types to larger ones and the function will still work:

1
2
3
4
5
6
template <typename T>
int strlen(const T *s){
    const T *p=s;
    for (;*p;p++);
    return p-s;
}
4. one is a char array the other is a pointer thats value is "Hello, world!" ?

Ok I need a question clarified to stop all this guesswork.

char* s="hi"; is a declaration of a pointer called s, that points to a location of memory. That memory is holding a char array [h][i][\0]
// this makes sense to me

char *s="hi"; is a declaration of a pointer called s, it's value is = "hi"
// this makes no sense, are you actually able to declare a pointer without using the typical construct?

is this correct?

Edit: never mind I just read this: http://www2.research.att.com/~bs/bs_faq2.html#whitespace
Last edited on
@helios
attempting to answer your 4th question...

is the answer related to the memory reserved by the compiler?
assuming that all string literals are pointers to constants as you mention above,

char string[]="Hello, World!\n"; should make the compiler reserve 30 bytes, 15 for the string literal (13 printable chars, 1 '\n', 1 '\0') and another 15 for the array. On the other,

char *string="Hello, World!\n"; should make the compiler reserve 19 bytes, 15 for the string literal and 4 for the pointer.

So in a first glance a pointer seems to be less memory-consuming

However, in the first case, a clever compiler (and maybe many compilers are this clever) could only reserve memory for the array and initialize it appropriately, thus saving the 15 bytes of the literal.

So, maybe our first judgment was wrong and an array is less memory-consuming than a pointer

I don't know, I mean the memory reserved for the two statements is definitely different, and which one is better depends on both the compiler's iq (hahaha) and the size of the string literal, but is this the answer you expect?... :/
Last edited on
#4 has nothing to do with the amount of memory used. It's about the nature of the object named 'string'. I want to know what it is in either case and what changes in the running program when it is created.
@helios
I know the answer to 5!!! :D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
using namespace std;

typedef int ARRAY[10];
typedef ARRAY *PARRAY; 

int main()
{

    ARRAY arr;
    PARRAY parr;

    parr=&arr;
    
    cout << "sizeof(arr): " << sizeof(arr) << endl; //this prints 40
    cout << "sizeof(parr): " << sizeof(parr) << endl; //this prints 4
    cout << "sizeof(*parr): " << sizeof(*parr) << endl; //this prints 40
    
    system("pause");
    return 0;
} 
Last edited on
Wrong.
why??? I mean I don't know if this was what u had in mind, but it works!!! There's no doubt it works, compile it and see for yourself
Last edited on
First, that's not a pointer to an array. It's a pointer to ten integers. If the array is of type T[N], the pointer has to be of type T *.
Second, you're using the type system to get the size at compile time. The question implies that what the pointer points to is determined at run time. It can be anything: an single integer, a stack array, a dynamic array. You can't know what the pointer will point to until run time.
some way to tell the size of the array pointed to by a pointer
All you can use to get the size is a pointer to the array's first element.

If you can do it inside this function, the solution is accepted:
1
2
3
void getsize(T *pointer){
    //your code here
}

As I said before, anything that is accepted by the compiler can be passed as the pointer.
Last edited on
oh, ok. then u should be more clear in asking your question, coz there you say a pointer to an array and now u say a pointer to the array's first element. Let me see what I can do...
"Pointer to an array" is typically understood to mean "pointer to the first element of an array", not "pointer to a stack array". Just like when you "delete a pointer" you don't actually delete the pointer; you "delete what the pointer points to".

EDIT: The difference is that parray+1!=array+1. parray+1==array+11.
Last edited on
I' ve thought of something but I'd like to tell you before I try writing any code coz it may be too far fetched... let's say that p is a pointer to the first element of the array. we make the assumption that the array contents remain constant during the call of getsize. we make a guess for the arrays size, let's say 50. then we make a new thread out of the getsize function, set a timer and check every let's say 100 miliseconds if the contents of p to p+size have changed. if there's a change, then the array's size is less than our guess. If there's no change for a long time, then probably the array's size is bigger than we guessed. And depending on the results we decrease or increase our guess for the array's size. I think that's a fair thing to do when you don't have anything but a pointer to the array's first element... What do you think???
Last edited on
ok, I've found it this time, and there's no way you can say it's wrong :D Since the size of an the array is known during compilation time... I ll use templates to define as many getsize functions as different (array sizes)*(array types) exist in my program!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

template< typename T, int N >
inline int getsize( T(&)[N] ) { return N ; }

int main()
{
    
    int array1[]={1,2,3,4,5,6};
    
    int * array2[]={array1,array1+1,array1+2};
    
    cout << getsize(array1) << endl;
    cout << getsize(array2) << endl;
    
    system("pause");
    return 0;
}
Last edited on
I think you need to keep thinking.

1. You don't know how long the array really is. If the pointer points to a single integer or an array shorter than 50, then god knows what p+50 points to.
2. You don't know if the user casted the pointer from something else, so you can't know how large the elements are.
3. Just because an element doesn't change, it doesn't mean it's outside the boundaries. An array of dynamic pointers would never change, even if all its elements were in constant use.
4.
then the array's size is less than our guess
Or maybe it's bigger. Is an array with 100 elements changing its 51st element so inconceivable?
If there's no change for a long time, then probably the array's size is bigger than we guessed.
Or maybe it's shorter, since the element is outside the boundaries. Or maybe its exactly 50 and the program hasn't gotten to that element, yet.
5. What will the function return while the other thread is running?
6. How will the calling thread be notified when the other thread finishes?
7. How will the thread pass its result to the calling thread?

EDIT: Still using compile time information. It breaks with these parameters:
1
2
3
4
5
int *p=new int[5];
getsize(p);
int array1[]={1,2,3,4,5,6};
p=array1;
getsize(p);
Last edited on
:/ damn... is what you're asking even possible? give me a hint... can it be always done or just in some special cases??? I mean, when you cast an array to a pointer, what u only have is the pointer... it could be pointing at anything... give me some directions to look for the answer...
Last edited on
The question was whether it could be done, not how to do it.
so, I guess, if I said "no, it can't be done" I could actually watch you reply...
"YES, you are absolutely right! It can't be done!!!"???
Pages: 1234