Asked  6 Months ago    Answers:  5   Viewed   25 times

As the heading says, What is the difference between

char a[] = ?string?; and 
char *p = ?string?;  

This question was asked to me in interview. I even dont understand the statement.

char a[] = ?string?

Here what is ? operator? Is it a part of a string or it has some specific meaning?



The first one is array the other is pointer.

The array declaration char a[6]; requests that space for six characters be set aside, to be known by the name a. That is, there is a location named a at which six characters can sit. The pointer declaration char *p; on the other hand, requests a place which holds a pointer. The pointer is to be known by the name p, and can point to any char (or contiguous array of chars) anywhere.

The statements

 char a[] = "string";
 char *p = "string"; 

would result in data structures which could be represented like this:

  a: | s | t | r | i | n | g |  |
     +-----+     +---+---+---+---+---+---+---+ 
  p: |  *======> | s | t | r | i | n | g | |    
     +-----+     +---+---+---+---+---+---+---+ 

It is important to realize that a reference like x[3] generates different code depending on whether x is an array or a pointer. Given the declarations above, when the compiler sees the expression a[3], it emits code to start at the location a, move three elements past it, and fetch the character there. When it sees the expression p[3], it emits code to start at the location p, fetch the pointer value there, add three element sizes to the pointer, and finally fetch the character pointed to. In the example above, both a[3] and p[3] happen to be the character l, but the compiler gets there differently.

Source: comp.lang.c FAQ list · Question 6.2

Tuesday, June 1, 2021
answered 6 Months ago

Sydius outlined the types fairly well:

  • Normal pointers are just that - they point to some thing in memory somewhere. Who owns it? Only the comments will let you know. Who frees it? Hopefully the owner at some point.
  • Smart pointers are a blanket term that cover many types; I'll assume you meant scoped pointer which uses the RAII pattern. It is a stack-allocated object that wraps a pointer; when it goes out of scope, it calls delete on the pointer it wraps. It "owns" the contained pointer in that it is in charge of deleteing it at some point. They allow you to get a raw reference to the pointer they wrap for passing to other methods, as well as releasing the pointer, allowing someone else to own it. Copying them does not make sense.
  • Shared pointers is a stack-allocated object that wraps a pointer so that you don't have to know who owns it. When the last shared pointer for an object in memory is destructed, the wrapped pointer will also be deleted.

How about when you should use them? You will either make heavy use of scoped pointers or shared pointers. How many threads are running in your application? If the answer is "potentially a lot", shared pointers can turn out to be a performance bottleneck if used everywhere. The reason being that creating/copying/destructing a shared pointer needs to be an atomic operation, and this can hinder performance if you have many threads running. However, it won't always be the case - only testing will tell you for sure.

There is an argument (that I like) against shared pointers - by using them, you are allowing programmers to ignore who owns a pointer. This can lead to tricky situations with circular references (Java will detect these, but shared pointers cannot) or general programmer laziness in a large code base.

There are two reasons to use scoped pointers. The first is for simple exception safety and cleanup operations - if you want to guarantee that an object is cleaned up no matter what in the face of exceptions, and you don't want to stack allocate that object, put it in a scoped pointer. If the operation is a success, you can feel free to transfer it over to a shared pointer, but in the meantime save the overhead with a scoped pointer.

The other case is when you want clear object ownership. Some teams prefer this, some do not. For instance, a data structure may return pointers to internal objects. Under a scoped pointer, it would return a raw pointer or reference that should be treated as a weak reference - it is an error to access that pointer after the data structure that owns it is destructed, and it is an error to delete it. Under a shared pointer, the owning object can't destruct the internal data it returned if someone still holds a handle on it - this could leave resources open for much longer than necessary, or much worse depending on the code.

Tuesday, June 1, 2021
answered 6 Months ago

the second function returns nothing

The string array in the second function:

char string[] = "Hello, World!";

has automatic storage duration. It does not exist after the control flow has returned from the function.

Whereas string in the first function:

char* string = "Hello, World!";

points to a literal string, which has static storage duration. That implies that, the string still exists after returning back from the function. What you are returning from the function is a pointer to this literal string.

Sunday, August 8, 2021
Timur Mustafaev
answered 4 Months ago

They're the same in most cases, basically Kotlin generates a synthetic property for the class attributes based on their getter, which you can use to assign values to and get values from.

//So, for most cases
textView.setText("some value");
//Is the same as
textView.text = "some value"
//The second is simply shorter and is the 'kotlin way' of assigning values

Now, here's the catch -

In most cases, this works fine. But, as mentioned, the synthetic property is generated from the getter, if there is a setter as well, then issues arise. The reason is that the getter and the setter may have different types. For example, EditText has Editable getter, now, kotlin creates a synthetic property text of the type Editable.

editText.setText("some value"); //Works
editText.text = "some value" //Won't work, will show an error stating that expected type is Editable
Monday, August 23, 2021
answered 4 Months ago


int a = 5;
int *b = &a;   
int *c = &b;

You get a warning because &b is of type int **, and you try to initialize a variable of type int *. There's no implicit conversions between those two types, leading to the warning.

To take the longer example you want to work, if we try to dereference f the compiler will give us an int, not a pointer that we can further dereference.

Also note that on many systems int and int* are not the same size (e.g. a pointer may be 64 bits long and an int 32 bits long). If you dereference f and get an int, you lose half the value, and then you can't even cast it to a valid pointer.

Saturday, September 4, 2021
Martin Vseticka
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :