Can you please tell me how to change the size of the buf vector into a dynamic length?
long five = 555;
char buf[256];
snprintf(buf, sizeof(buf), "%d", five);
THX!
How to change my code with std::vector<std::string>buf; in order to work correctly?
I have error:
vector is not a member of std;
buf was not declared in this scope and error: expected primary-expression before ">" token
In C++, you can't. You will have to allocate it dynamically somehow, or better still use a dynamic data structure like a std::vector.
Try:
#include <vector>
#include <string>
long five = 555;
// using vector
std::vector<char> buf1(256);
snprintf(&buf1[0], buf1.size(), "%d", five);
// Or using string
std::string buf2(256);
snprintf(&buf2[0], buf2.size(), "%d", five);
Though rather than using snprintf() I would look up how to use stringstream.
if you're really opposed to using the vector class, you could implement the dynamic memory yourself. Create a function for adding to the array when theres not enough memory to store the new values. It would malloc new memory, copy the contents over, append new values, delete the old memory, then return a pointer to the new array. They amount new memory that you would use would depend on your application.(ie. just enough memory to store new values to conserve memory, or a lot more(eg double) than the old size so you wouldn't have to call this function as often.
You probably want to make a vector of characters, not a vector of strings.
The second error I suspect is a missing space character before the variable name.
Related
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).
I want to create an array of chars (char path[size] = "") while getting "size" from user.
When I try something like this:
int size = getSizeFromUser();
char path[size] = "";
I get a warning says "expression must have a constant value".
How can I do it right?
Thanks a lot!
How can I do it right?
Variable length arrays aren't standard c++. The correct way to do it is to use a std::vector or a std::string instead of a raw array:
int size = getSizeFromUser();
std::string path(size,'\0');
In order to create a table with the users size you have to allocate your memory on the heap
int size = 4;
char *path = new char[size];
after using your array you have to manually delete it from the heap
delete path;
If you declare char path[size]; then size has to be known at compile time. You read it at runtime so you need to use dynamic memory allocation, like char* path = new char[size]; and when you are finished call delete []path;.
If you want this to be a string with size visible characters, please consider that C-strings are null-terminated, meaning that you would have to reserve one extra char at the end of the array and set it to 0.
A better solution for a C++ program would probably be to use a std::string instead of a char*.
When creating an array, its size must be constant.
If you want a dynamically sized array, you will have to allocate memory for it and you'll also need to free it when you're done with it.
To simply all these its always nice to use std::string
In below code example, memory for an integer is dynamically allocated and the value is copied to the new memory location.
main() {
int* c;
int name = 809;
c = new int(name);
cout<<*c;
}
But, when I try to do the same with a char string it doesn't work.
Why is this?
int main() {
char* p;
char name[] = "HelloWorld";
p = new char(name);
cout << p;
}
Your second example doesn't work, because char arrays work differently than integer variables. While single variables can be constructed this way, this doesn't work with (raw) arrays of variables. (As you have observed.)
In C++ you should try to avoid handling pointers and raw arrays as much as you can. Instead, you'd rather use the standard library containers to take a copy of that string to an array of dynamically allocated memory. std::string and std::vector<char> are especially suitable in this case. (Which one should be preferred depends a bit on the semantics, but probably it's the std::string.)
Here's an example:
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
int main(){
char name[] = "Hello World";
// copy to a std::string
std::string s(name);
std::cout << s << '\n';
// copy to a std::vector<char>
// using strlen(name)+1 instead of sizeof(name) because of array decay
// which doesn't occur here, but might be relevant in real world code
// for further reading: https://stackoverflow.com/q/1461432
// note that strlen complexity is linear in the length of the string while
// sizeof is constant (determined at compile time)
std::vector<char> v(name, name+strlen(name)+1);
std::cout << &v[0] << '\n';
}
The output is:
$ g++ test.cc && ./a.out
Hello World
Hello World
For reference:
http://en.cppreference.com/w/cpp/string/basic_string
http://en.cppreference.com/w/cpp/container/vector
Your second code snippet does not work because new int(name) initializes an int from an int, while new char(name) tries to initialize a char from a char[11] array.
There is no array constructor taking an array in C++. In order to make a copy of an array, you must allocate an array, and then copy data into it:
p = new char[sizeof(name)];
std::memcpy(p, name, sizeof(name));
In the first case you allocate memory for a single int object, and initialize with a single int value. Great, this works.
In the second case you allocate memory for a single char object, and initialize it with an array of characters. It does not work, an array of objects does not fit in a memory of a single object. Besides, the array has a different type, so the initialization is ill-formed.
To allocate memory for an array of characters (such as a string), you can use new[]:
char* ptr = new char[11]{"HelloWorld"};
PS. The GNU compiler (until the current version 7 at least) and clang (until version 4) have a bug which breaks the above initialization. A workaround is to copy the string after allocation.
PPS. While it is useful to learn these things, don't do manual memory management in actual programs. Use RAII containers such as std::string for strings and std::unique_ptr for single dynamic objects.
Your code doesn't work as you are trying to initialize a char instead of array of characters. In order to dynamically allocate memory, you need to allocate the memory and then copy over the content.
p = new char[strlen(name) +1];
std::strcpy(p, name);
can we declare size to a pointer
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char (*ptr)=new char[3];
strcpy(ptr,"ert");
cout<<ptr<<endl;
return 0;
}
what is the meaning of this line char *ptr=new char[3] if it allocates size to ptr.since i have given the size as 3 and the string as "ert"it has to show error since the string length is too long but it doesn't .can we allocate size to pointers if so how?
You need 4 characters:
char *ptr=new char[4];
strcpy(ptr,"ert");
One extra space for the nul terminator:
|e|r|t|\0|
It's not the size of the pointer that you've declared, but the size of the character array that the pointer points to.
strcpy() does not know the length of the array that the pointer points to - it just knows it's got a pointer to the first byte it can copy into, and trusts that you know there's enough room for the copy to be made. Thus it's very fast, but it's also rather dangerous and should be used only when you're sure the destination is large enough.
strncpy() is worth looking into for some extra safety, but you still have to know that the target pointer points to something large enough for the size you specify (it protects more against the size of the source than the size of the target).
The lesson to learn here is that C and C++ won't give you any help - the compiler trusts you to get your buffer sizes right, and won't do any checking on your behalf either at compile time or runtime. This allows programs to run extremely fast (no runtime checking) but also requires the programmer to be a lot more careful. If you're writing in C++ which your tags suggest, for normal string handling you should definitely be using the std::string class unless you have a specific reason to need C-style string handling. You may well have such a reason from time to time, but don't do it unless you have to.
This statement
char (*ptr)=new char[3];
at first allocates in the heap unnamed character array with 3 elements and then the address of the first element of the array is assigned to pointer ptr.
The size of the pointer will not be changed whether you initialize it as in the statement above or the following way
char (*ptr)=new char;
that is sizeof( ptr ) will be the same and equal usually either to 4 or 8 bytes depending on the environment where the program will be compiled.
C++ does not check bounds of arrays. So in this statement
strcpy(ptr,"ert");
you have undefined behaviour of the program because string literal "ert" has four elements including the terminating zero.
I need to be able to set the size of an array based on the number of bytes in a file.
For example, I want to do this:
// Obtain the file size.
fseek (fp, 0, SEEK_END);
size_t file_size = ftell(fp);
rewind(fp);
// Create the buffer to hold the file contents.
char buff[file_size];
However, I get a compile time error saying that the size of the buffer has to be a constant.
How can I accomplish this?
Use a vector.
std::vector<char> buff(file_size);
The entire vector is filled with '\0' first, automatically. But the performance "lost" might not be noticable. It's certainly safer and more comfortable. Then access it like a usual array. You may even pass the pointer to the data to legacy C functions
legacy(&buff[0]); // valid!
You should use a std::vector and not an array.
Real arrays require you to specify their size so that the compiler can create some space for them -- this is why the compiler complains when you don't supply a constant integer. Dynamic arrays are represented by a pointer to the base of the array -- and you have to retrieve the memory for the dynamic array yourself. You may then use the pointer with subscript notation. e.g.,
int * x;
x = (int *) malloc( sizeof(int) *
getAmountOfArrayElements() /* non-const result*/
);
x[5] = 10;
This leads to two types of problems:
Buffer over/under flows : you might subscript-index past either end of the array.
You might forget to release the memory.
Vector provides a nice little interface to hide these problems from you -- if used correctly.
Replace
char buff[file_size];
with
char *buff = new char[file_size];
and once the use of the buff is done..you can free the memory using:
delete[] buff;
There are two points in your question I'd like to cover.
The actual question, how do you create the array. Johannes answered this. You use a std::vector and create it with a size allocation.
Your error message. When you declare an array of some type, you must declare it with a constant size. So for example
const int FileSize = 1000;
// stuff
char buffer[FileSize];
is perfectly legitimate.
On the other hand, what you did, attempting to declare an array with variable size, and then not allocating with new, generates an error.
Problem is that buff needs be created on the heap (instead of stack). Compiler want s to know the exact size to create on the stack.
char* buff = new char[file_size];