Passing an array as a function parameter in C++ - c++

In C++, arrays cannot be passed simply as parameters. Meaning if I create a function like so:
void doSomething(char charArray[])
{
// if I want the array size
int size = sizeof(charArray);
// NO GOOD, will always get 4 (as in 4 bytes in the pointer)
}
I have no way of knowing how big the array is, since I have only a pointer to the array.
Which way do I have, without changing the method signature, to get the size of the array and iterate over it's data?
EDIT: just an addition regarding the solution. If the char array, specifically, was initialized like so:
char charArray[] = "i am a string";
then the \0 is already appended to the end of the array. In this case the answer (marked as accepted) works out of the box, so to speak.

Use templates. This technically doesn't fit your criteria, because it changes the signature, but calling code does not need to be modified.
void doSomething(char charArray[], size_t size)
{
// do stuff here
}
template<size_t N>
inline void doSomething(char (&charArray)[N])
{
doSomething(charArray, N);
}
This technique is used by Microsoft's Secure CRT functions and by STLSoft's array_proxy class template.

Without changing the signature? Append a sentinel element. For char arrays specifically, it could be the null-terminating '\0' which is used for standard C strings.
void doSomething(char charArray[])
{
char* p = charArray;
for (; *p != '\0'; ++p)
{
// if '\0' happens to be valid data for your app,
// then you can (maybe) use some other value as
// sentinel
}
int arraySize = p - charArray;
// now we know the array size, so we can do some thing
}
Of course, then your array itself cannot contain the sentinel element as content.
For other kinds of (i.e., non-char) arrays, it could be any value which is not legal data. If no such value exists, then this method does not work.
Moreover, this requires co-operation on the caller side. You really have to make sure that the caller reserves an array of arraySize + 1 elements, and always sets the sentinel element.
However, if you really cannot change the signature, your options are rather limited.

In general when working with C or low-level C++, you might consider retraining your brain to never consider writing array parameters to a function, because the C compiler will always treat them as pointers anyway. In essence, by typing those square brackets you are fooling yourself in thinking that a real array is being passed, complete with size information. In reality, in C you can only pass pointers. The function
void foo(char a[])
{
// Do something...
}
is, from the point of view of the C compiler, exactly equivalent to:
void foo(char * a)
{
// Do something
}
and obviously that nekkid char pointer contains no length information.
If you're stuck in a corner and can't change the function signature, consider using a length prefix as suggested above. A non-portable but compatible hack is to specify the array length in an size_t field located before the array, something like this:
void foo(char * a)
{
int cplusplus_len = reinterpret_cast<std::size_t *>(a)[-1];
int c_len = ((size_t *)a)[-1];
}
Obviously your caller needs to create the arrays in the appropriate way before passing them to foo.
Needless to say this is a horrible hack, but this trick can get out of trouble in a pinch.

It actually used to be a quite common solution to pass the length in the first element of the array. This kind of structure is often called BSTR (for “BASIC string”), even though this also denoted different (but similar) types.
The advantage over the accepted solution is that determining the length using a sentinel is slow for large strings. The disadvantage is obviously that this is a rather low-level hack that respects neither types nor structure.
In the form given below it also only works for strings of length <= 255. However, this can easily be expanded by storing the length in more than one byte.
void doSomething(char* charArray)
{
// Cast unnecessary but I prefer explicit type conversions.
std::size_t length = static_cast<std::size_t>(static_cast<unsigned char>(charArray[0]));
// … do something.
}

if it's nullterminated, strlen() would work.

You can't determine the size from charArray alone. That information is not automatically passed to the function.
Of course if it's a null-terminated string you can use strlen(), but you have probably considered that already!
Consider passing a std::vector<char> & parameter, or a pair of pointers, or a pointer plus a size parameter.

This is actually more C than C++, in C++ you'd probably rather use a std::vector. However, in C there's no way to know the size of an array. The compile will allow you to do a sizeof if the array was declared in the current scope, and only if it was explicitly declared with a size (EDIT: and "with a size", I mean that it was either declared with an integer size or initialized at declaration, as opposed to being passed as a parameter, thanks for the downvote).
The common solution in C is to pass a second parameter describing the number of elements in the array.
EDIT:
Sorry, missed the part about not wanting to change the method signature. Then there's no solution except as described by others as well, if there's some data that is not allowed within the array, it can be used as a terminator (0 in C-strings, -1 is also fairly common, but it depends on your actual data-type, assuming the char array is hypothetical)

In order for a function to know the number of items in an array that has been passed to it, you must do one of two things:
Pass in a size parameter
Put the size information in the array somehow.
You can do the latter in a few ways:
Terminate it with a NULL or some
other sentinel that won't occur in
normal data.
store the item count in the first entry if the array holds numbers
store a pointer to the last entry if the array contains pointers

try using strlen(charArray);
using the cstring header file. this will produce the number of characters including spaces till it reaches the closing ".

You are guarranteed to receive 4 in a 32-bit PC and that's the correct answer. because of the reason explained here and here.
The short answer is, you are actually testing the sizeof a pointer rather than an array, because "the array is implicitly converted, or decays, into a pointer. The pointer, alas, doesn't store the array's dimension; it doesn't even tell you that the variable in question is an array."
Now that you are using C++, boost::array is a better choice than raw arrays. Because it's an object, you won't loose the dimention info now.

I think you can do this:
size_t size = sizeof(array)/sizeof(array[0]);
PS: I think that the title of this topic isn't correct, too.

Dude you can have a global variable to store the size of the array which will be accessible throughout the program. At least you can pass the size of the array from the main() function to the global variable and you will not even have to change the method signature as the size will be available globally.
Please see example:
#include<...>
using namespace std;
int size; //global variable
//your code
void doSomething(char charArray[])
{
//size available
}

Related

Is there any way to find Dynamic memory size like sizeof facelity?

I am looking for something which give me size which taken by str character pointer.
int main()
{
char * str = (char *) malloc(sizeof(char) * 100);
int size = 0;
size = /* library function or anything use to find size */
printf("Total size of str array - %d\n", size);
}
I want prove that give memory is 100 bytes.
Is any one have any idea about this ?
A raw pointer only knows it points to a single element of it's type. If that thing it points to happens to be part of an array, the pointer doesn't know and there's no way to get that information from it.
You want to instead use types that do know their size, like for example; std::string, std::array or std::vector.
The C and C++ standards do not provide a way to get, from an address, the amount of memory that was requested in the call to malloc that returned that address.
Some C or C++ implementations provide a way to get the amount of memory that was provided at the given address, such as malloc_size. The amount provided may be greater than the amount that was requested.
If the memory contains a string, which is an array of characters terminated by a null character, then you can determine the length of the string by counting characters up to the null character. This function is provided by the standard strlen function. This length is different from the space allocated unless, of course, the string happens to fill the space.
There is no (good, standard, portable) way to tell from a pointer value alone whether it's the first element of an array or not, nor how many elements follow it. That information has to be tracked separately.
If you're writing in C++, don't do your own memory management if you can help it. Use a standard container type like std::vector or std::map (or std::string for text). If you must do your own memory management, use the new and delete operators instead of the *alloc and free library functions, and wrap a class around those operations that also keeps track of how many elements have been allocated (which, like std::vector and std::map, is returned via a read-only size() method).

Sizeof is returning pointer size rather than array size. Any other way to find the size?

I am working on a coding assignment for my class and I ran into a problem!
I have this constructor here, for a String object:
String::String(char str[]) {
size = (sizeof(str)/sizeof(str[0]));
data = new char[size];
for (int i = 0; i < size; ++i) {
data[i] = str[i];
}
}
Here is part of the main I was provided:
char test[11] = "Hello world";
String two(test);
cout << "The length of String two is: " <<
two.length() << endl;
cout << "The value of String two is: ";
two.print();
So when I run this, I would get 8 for the size (should be 11). However, after some research, I figured out it is because the sizeof(str) is returning the byte size of a pointer, rather than the entire array.
So is there any way to get the size of the whole array with what I have? I am not supposed to manipulate the provided main, therefore I cannot add an int size to the parameters, which would be the obvious solution.
I've been stuck on this one for a bit, thanks for any help and suggestions,
Array decays to pointer when passed to a function.
You have to either pass the length to the function, pass a STL container e.g. std::vector or use strlen() inside function. (Note that strlen() need a terminating null-character to work properly and you have to add that to your array)
You can not get size of array at runtime in C. At runtime, array is just the address. The size is simply not stored anywhere. In source code, at compile time, in a place where compiler knows the size, you can use sizeof operator, but that gets essentially converted to a constant numeric literal, ie. same as writing the right number there yourself (VLAs are a bit more complex case, and of course using sizeof can create portable code unlike hard-coded number).
To make matters worse (for understanding C), when you have a function parameter that looks like an array, it really is a pointer. Even if you give it static size in the parameter list, sizeof still it gives you size of pointer, for example. Only non-parameter variables can actually be arrays, with sizeof working as expected.
You have to pass the size somehow (usually as extra parameter) or have some other way of telling where the data ends (such as strings' '\0' at the end).
Use a vector instead of char array. You can get size by calling size() method of vector container. If you want to use a char array, then it is a common practice in c programming to pass size as second parameter in the function.
You will only get size of array using sizeof() function on the function stack in which the array is defined and if the array size is known in compile time.

returning a "variable string literal" from a function

I have some function that needs to return a const char* (so that a whole host of other functions can end up using it).
I know that if I had something defined as follows:
const char* Foo(int n)
{
// Some code
.
.
.
return "string literal, say";
}
then there is no problem. However am I correct in saying that if Foo has to return some string that can only be determined at runtime (depending on the parameter n, (where each n taking any value in [0, 2^31-1] uniquely determines a return string)) then I have to use the heap (or return objects like std::string which use the heap internally)?
std::string seems too heavyweight for what I want to accomplish (at least two functions will have to pass the parcel), and allocating memory inside Foo to be freed by the caller doesn't strike me as a safe way of going forward. I cannot (easily) pass in references to the objects that need this function, and not that I believe it is possible anyway but macro trickery is out of the question.
Is there something simple that I have not yet considered?
EDIT
Thanks to all for the answers, I'll go for std::string (I suppose in a roundabout fashion I was asking for confirmation that there is no way of hinting to the compiler that it should store the contents of some char[] in the same place that it stores string literals). As for "heavyweight" (and I'm pleasantly surprised that copying them isn't as wasteful as I thought) that wasn't the best way of putting it, perhaps "different" would have been closer to my initial apprehension.
If you mean that your function chooses between one of n known-at-compile-time strings, then you can just return a const char * to any one of them. A string literal has static storage duration in C and C++, meaning that they exist for the lifetime of the program. Therefore it is safe to return a pointer to one.
const char* choose_string(int n)
{
switch(n % 4)
{
case 0: return "zero";
case 1: return "one";
case 2: return "two";
case 3: return "three";
}
}
If your function dynamically generates a string at runtime, then you have to either pass in a (char *buf, int buf_length) and write the result into it, or return a std::string.
In C++, returning a std::string is probably the right answer (as several others have already said).
If you don't want to use std::string for some reason (say, if you were programming in C, but then you would have tagged the question that way), there are several options for "returning" a string from a function. None of them are pretty.
If you return a string literal, what you're really returning is a pointer to the first character of the array object associated with that string literal. That object has static storage duration (i.e., it exists for the entire execution of your program), so returning a pointer to it is perfectly safe. This is obviously inflexible.
You can allocate an array on the heap and return a pointer to it. That lets the called function determine how long it needs to be, but it places the burden on the caller to deallocate the memory when it's no longer needed.
You can return a pointer to (the first element of) a static array defined inside the function. This is inflexible in that the maximum length has to be determined at compile time. It also means that successive calls to the function will clobber the result. The asctime() function, defined in <time.h> <ctime> does this. (I once wrote a function that cycled through the elements of a static array of arrays, so that 6 successive calls would not clobber previous results, but the 7th would. That was probably overkill.)
You can require the caller to pass in a pointer to (the first element of) an array that the caller itself must allocate, probably along with a separate argument that specifies the length of the caller's array. This requires the caller to know how long the string might be, and probably to be able to handle the error of not reserving enough space.
And now you know why C++ provides library features like std::string that take care of all this stuff for you.
Incidentally, the phrase "variable string literal" doesn't make a lot of sense. If something is a literal, it's not variable. Probably "variable string" is what you meant.
The easiest solution might be to return a std::string.
If you want to avoid std::string, one alternative is to have the caller pass a char[] buffer to the function. You might also want to provide a function that can tell the caller how big of a buffer will be needed, unless an upper bound is known statically.
Use std::string, but if you really want... A common pattern used in C programming is to return the size of the final result, allocate a buffer, and call the function twice. (I apologize for the C style, you want a C solution I give a C solution :P )
size_t Foo(int n, char* buff, size_t buffSize)
{
if (buff)
{
// check if buffSize is large enough if so fill
}
// calculate final string size and return
return stringSize;
}
size_t size = Foo(x, NULL, 0); // find the size of the result
char* string = malloc(size); // allocate
Foo(x,string, size); // fill the buffer
(Donning asbestos suit)
Consider just leaking the memory.
const char* Foo(int n)
{
static std::unordered_map<int, const char*> cache;
if (!cache[n])
{
// Generate cache[n]
}
return cache[n];
}
Yup, this will leak memory. Up to 2^32 strings worth of them. But if you had the actual string literals, you would always have all 2^32 strings in memory (and clearly require a 64 bits build - just the \0 alone take 4GB!)

discover char* parameter size

I have a function that have a char* as parameter to receive some informations from inside the function. (int foo(char* param1))
How can I be sure that this parameter have the enough allocated space to receive all the information I need to put in?
I can be sure if it is, or not, a valid pointer, but I haven't found a way to be sure about the size/length allocated to the parameter.
I can't change the function (can't add another parameter with the size).
AFIAK, C++ does not have any facility to verify the amount of space allocated to a pointer. If the input points to a NULL-terminated array of chracters (i.e. a c-string), then you can use strlen(). Typically these kinds of functions in C and C++ must be well-documented as to what is expected from the parameters. The function is typically implemented assuming the the caller honors the documented contract.
If I have understood the question correctly, there is no way for you to ascertain the size of valid memory associated with the pointer. If this was pointing to an array of data, the usual way to pass a size parameter but if you do not have that option, you do not know what you will be accessing
Easy answer: you can't.
Little more complicated C-style answer: if that array of chars has a terminating NUL (0) byte, you can use strlen().
OS-specific answer: if the memory for the array was obtained using malloc(), you can use malloc_size() and malloc_usable_size() at least on OS X and Linux, respectively. On windows, for applications that use the Microsoft C Runtime, there's the _msize() function.
You can't be sure. Not really. The only practical check you can do for pointer validity is to check if it is not NULL.
As far as knowing size of the the buffer param1 points to, the only thing that comes to mind is this stupid hack. Before callting function, put the size of the buffer in at the beginning of the buffer that param1 points to. Then, copy your data into the buffer, overwriting the size when you are done with checks.
Like this:
*(unsigned int*)param1 = buf_size;
foo(param1);
int foo(char* param1)
{
if (0 == param1)
{
// fail
}
unsigned int buf_size = *(unsigned int*)param1;
if (buf_size < whateverlimit)
{
// fail
}
// copy data into the buffer
}
I have not compiled this code so it might need some corrections.

good manier to get char[] from another function. Starting thinking in c/c++

As I understood the correct programming style tells that if you want to get string (char []) from another function is best to create char * by caller and pass it to string formating function together with created string length. In my case string formating function is "getss".
void getss(char *ss, int& l)
{
sprintf (ss,"aaaaaaaaaa%d",1);
l=11;
}
int _tmain(int argc, _TCHAR* argv[])
{
char *f = new char [1];
int l =0;
getss(f,l);
cout<<f;
char d[50] ;
cin>> d;
return 0;
}
"getss" formats string and returns it to ss*. I thought that getss is not allowed to got outside string length that was created by caller. By my understanding callers tells length by variable "l" and "getcc" returns back length in case buffer is not filled comleatly but it is not allowed go outside array range defined by caller.
But reality told me that really it is not so important what size of buffer was created by caller. It is ok, if you create size of 1, and getss fills with 11 characters long. In output I will get all characters that "getss" has filled.
So what is reason to pass length variable - you will always get string that is zero terminated and you will find the end according that.
What is the reason to create buffer with specified length if getss can expand it?
How it is done in real world - to get string from another function?
Actually, the caller is the one that has allocated the buffer and knows the maximum size of the string that can fit inside. It passes that size to the function, and the function has to use it to avoid overflowing the passed buffer.
In your example, it means calling snprintf() rather than sprintf():
void getss(char *ss, int& l)
{
l = snprintf(ss, l, "aaaaaaaaaa%d", 1);
}
In C++, of course, you only have to return an instance of std::string, so that's mostly a C paradigm. Since C does not support references, the function usually returns the length of the string:
int getss(char *buffer, size_t bufsize)
{
return snprintf(buffer, bufsize, "aaaaaaaaaa%d", 1);
}
You were only lucky. Sprintf() can't expand the (statically allocated) storage, and unless you pass in a char array of at least length + 1 elements, expect your program to crash.
In this case you are simply lucky that there is no "important" other data after the "char*" in memory.
The C runtime does not always detect these kinds of violations reliably.
Nonetheless, your are messing up the memory here and your program is prone to crash any time.
Apart from that, using raw "char*" pointers is really a thing you should not do any more in "modern" C++ code.
Use STL classes (std::string, std::wstring) instead. That way you do not have to bother about memory issues like this.
In real world in C++ is better to use std::string objects and std::stringstream
char *f = new char [1];
sprintf (ss,"aaaaaaaaaa%d",1);
Hello, buffer overflow! Use snprintf instead of sprintf in C and use C++ features in C++.
By my understanding callers tells length by variable "l" and "getcc" returns back length in case buffer is not filled comleatly but it is not allowed go outside array range defined by caller.
This is spot on!
But reality told me that really it is not so important what size of buffer was created by caller. It is ok, if you create size of 1, and getss fills with 11 characters long. In output I will get all characters that "getss" has filled.
This is absolutely wrong: you invoked undefined behavior, and did not get a crash. A memory checker such as valgrind would report this behavior as an error.
So what is reason to pass length variable.
The length is there to avoid this kind of undefined behavior. I understand that this is rather frustrating when you do not know the length of the string being returned, but this is the only safe way of doing it that does not create questions of string ownership.
One alternative is to allocate the return value dynamically. This lets you return strings of arbitrary length, but the caller is now responsible for freeing the returned value. This is not very intuitive to the reader, because malloc and free happen in different places.
The answer in C++ is quite different, and it is a lot better: you use std::string, a class from the standard library that represents strings of arbitrary length. Objects of this class manage the memory allocated for the string, eliminating the need of calling free manually.
For cpp consider smart pointers in your case propably a shared_ptr, this will take care of freeing the memory, currently your program is leaking memory since, you never free the memory you allocate with new. Space allocate by new must be dealocated with delete or it will be allocated till your programm exits, this is bad, imagine your browser not freeing the memory it uses for tabs when you close them.
In the special case of strings I would recommend what OP's said, go with a String. With Cpp11 this will be moved (not copied) and you don't need to use new and have no worries with delete.
std::string myFunc() {
std::string str
//work with str
return str
}
In C++ you don't have to build a string. Just output the parts separately
std::cout << "aaaaaaaaaa" << 1;
Or, if you want to save it as a string
std::string f = "aaaaaaaaaa" + std::to_string(1);
(Event though calling to_string is a bit silly for a constant value).