Trying to read invalid data from array - c++

#include<iostream>
#include<string>
#include<sstream>
#include <typeinfo>
using namespace std;
int main()
{
setlocale(LC_ALL, "");
string str = "5 7 3";
int length = str.length();
char* arr = new char[length];
cout << arr[2] << endl;
/*
int max = stoi(string(1, arr[0]));
for (int i = 0; i < length; i++) {
if(arr[i] != ' '){
if (stoi(string(1, arr[i])) > max) {
max = stoi(string(1, arr[i]));
}
}
}
cout << max << endl;
*/
delete[] arr;
}
I'm getting error C6385 " Reading invalid data" when I'm trying to cout arr[2]. When I'm trying to cout arr[0], for instance, I get char 'H' in console, I don't really understand why is there 'H' if I don't have H in my str

char* arr = new char[length];
cout << arr[2] << endl;
These are the only lines that matter for your question. The first one allocates a character array. The data stored in the array at this pointer is unknown. It could be zeroes, it could be complete garbage. In your case, there happens to sometimes be an 'H' in index 2. If you run it in a hour it could be different - likely the last thing stored at the memory address of that array element had an ascii value of H.

arr[] doesn't contain your str because you didn't do anything for that to happen. Also, to fit the string content , you would need new char[length + 1] to account for terminating zero.
After all, you don't need convert a string to an array in most cases, a string already contains i. There is std::stoi function that works with strings.

char* arr = new char[length];
that means, reseve memory and call it arr, it as memory as lenght char* size, this memory can conteins another runtime var or something unreadable for C++, so when u try:
cout << arr[2] << endl;
If u can read it, it will give you that value, as 'H', but if u cant it should get nothing or strange icon.
Just reboot PC and you arent going to get another 'H' on your arr[0]
Anyway as your code looks u need to change it:
char* arr = new char[length];
cout << arr[2] << endl;
for:
char* arr = new char[length + 1];

Related

How I can handle with error about entered size of string exceeds the set size of char array?

I need some kind of error handler if I enter a string larger than the set size.
cout << "Enter long of the string" << endl;
cin >> N;
char* st = new char[N];
char* st1 = new char[N];
for (int i = 0; i < N; ++i) {
*(st1 + i) = ' ';
}
cout << "Enter string in the end put 0,without whitespace in the end." << endl;
cin.getline(st, N, '0');
First some comments.
Do not use C-Style arrays in C++ (like char data[N])
Always use std::string for strings
Never use char arrays for strings
Never ever use raw pointers for owned memory in C++
Neally never use new in C++
Avoid using pointer arithmetic with raw pointers pointing to owned memory
So, you should rethink your design. Start doing it correctly in the first place.
To answer you concrete question: If you read the documentation of the getline, then you can see that
count-1 characters have been extracted (in which case setstate(failbit) is executed).
So, the failbit will be set. You can check this with
if (std::cin.rdstate() == std::ios_base::failbit)
But as you can also read in the documentation
Extracts characters from stream until end of line or the specified delimiter delim.
So, it will not work, as you expect, It will try to read until 0 has been read. I think it will not work for you.
You also need to delete the newed memory. Otherwise, you are creating a memory hole. Look at you example again and try it:
#include <iostream>
int main() {
size_t N;
std::cout << "Enter maximum length of the string\n";
std::cin >> N;
char* st = new char[N];
char* st1 = new char[N];
for (size_t i = 0U; i < N; ++i) {
*(st1 + i) = ' ';
}
std::cout << "Enter string in the end put 0, without whitespace in the end.\n";
std::cin.getline(st, N, '0');
if (std::cin.rdstate() == std::ios_base::failbit) {
std::cin.clear();
std::cout << "\nError: Wrong string entered\n\n";
}
delete[] st;
delete[] st1;
return 0;
}
Solution for all your problems: Use std::string and std::getline

I am trying to count the contents in a char array till the null-termination, but each time I compile i get a number larger than my array

No matter what value I set for the size of my array, the function I wrote returns a value some degree larger.
I've tried, while(*str++) and removing the str++ from inside the while loop, instead of what is there now.
I am using Visual Studio 2019.
int strlen(char* str)
{
int i = 0;
while (*str != '\0')
{
i++;
str++;
}
return i;
}
int main()
{
char line[1];
char* v = line;
char* s = new char[1];
cout << "for s " << strlen(s) << endl;
cout << "for v " << strlen(v) << endl;
}
You are neglecting to null-terminate your strings. Your function is iterating past the end of the array and causing Undefined Behavior. Some string-manipulation functions will put the null at the end, but if you want your string to have a terminal null, you must put it there yourself.
char line[2];
char* v = line;
line[0]='x';
line[1]= '\0';
The contents of your arrays are undefined. You are not filling any of the arrays with any characters, let alone with any null terminators. It is undefined behavior to call strlen() on a character array that is not properly null terminated.

Only the first character of token is stored in array in c++

int main(void)
{
char *text = (char*)malloc ( 100 *sizeof( char));
cout << "Enter the first arrangement of data." << endl;
cin.getline(text, 100);
char *token = strtok(text, " ");
char *data = (char*)malloc ( 100*sizeof( char));
while ( token != NULL )
{
if (strlen(token) > 0)
{
cout << token << endl; // to test if the token is correct so far.
data[Tcount++] = *token;
}
token = strtok(NULL, " ");
}
for(i = 0; i < Tcount; i++)
{
cout << data[i] << endl;
}
For some reason when i enter in a user input of xp = a + 1, the output of data[i] is:
x
=
a
+
1
Do you know why the first token (should be xp) is only being stored in data[] as x?
Thanks.
strtok has some internal state that you aren't taking into account. See here:
http://www.cplusplus.com/reference/cstring/strtok/
This line only grabs the first character of the token:
data[Tcount++] = *token;
Then this line skips to the next token (due to internal state of strtok remembering location of last token):
token = strtok(NULL, " ");
You need to nest another loop inside the while loop that contains these two lines, so that you read all the characters in a token. Only then can you call strtok again without losing data.
There are a few things not quite correct.
The part "data[Tcount++] = *token;" is assigning a value of "token" (char) to a "data[Tcount]" which is also a char.
I believe that the "data" contains an address to the start of 100 * sizeof (char) in the memory. And when "data[i]" is accessed it is a single "char"
for(i = 0; i < Tcount; i++) {
cout << data[i] << endl; }
If you want to store a list of strings (an array of chars), you need to use 2 dimensional arrays (or pointers) so each array (or pointer) can store an array (or pointer).
For example, use data[][] or **data. If you would like to refresh definitions of these please refer to the links below;
click reference to pointer of pointer in c++.
click reference to arrays in c++.
Because your token array is a char array (*char). You need to create a string array (**char) to store "xp" since it is not a char variable.

A simple vector, how can I reassign the address for a new array correctly

I am trying to create a simple version of a vector. It seems to be working if I look only at what I am storing, but there is one thing that concerns me. Here is my code:
#include <iostream>
using namespace std;
int main(){
char* arr = new char[1];
int size = 1; // current size of the array
int num_chars = 0; // how many characters are stored so far
char c;
while (true)
{
cout << ">";
cin >> c;
if (c == '!') break;
if (num_chars == size)
{
size *= 2;
char* new_arr = new char[size];
cout << "Old array address: " << &arr << endl;
cout << "New array address: " << &new_arr << endl;
for (int i = 0; i < size/2; i++) // copy arr to new_arr
new_arr[i] = arr[i];
delete[] arr;
arr = new_arr;
}
arr[num_chars++] = c;
for (int i = 0; i < num_chars; i++)
cout << arr[i];
cout << endl;
cout << &arr << endl;
}
delete[] arr;
return 0;
}
the program accepts characters one at a time, and they are stored in an array which grows dynamically, finishing when you enter an exclamation mark. I added some cout statements to check my input and where the arrays are being stored.
When I allocate new_arr it gets a new address, then I copy over the memebers of arr to the new arr, delete arr, and assign arr to point to new_arr. The part that concerns me is that when I check the memory locations of arr after it gets reassigned, it's the same as it was before, so it looks like I'm just writing past the end of the original array. How can I correctly reassign the pointer to the new array?
Here is some sample output:
>a
a
0x7fff5fbff760
>b
Old array address: 0x7fff5fbff760
New array address: 0x7fff5fbff748
ab
0x7fff5fbff760
>c
Old array address: 0x7fff5fbff760
New array address: 0x7fff5fbff748
abc
0x7fff5fbff760
You are printing out addresses of pointers themselves, not addresses of the arrays (i.e. the contents of the pointers).
The location in memory where you store the address of the array (i.e. the address of variable arr) stays the same. It's not supposed to change. Thus, &arr is always the same. But the value stored in that location does change (as it would be expected).
Change the code to
cout << "Old array address: " << static_cast<void*>(arr) << endl;
and see the difference.
(static_cast<void*>(arr) casts type of arr from char* to void*. The reason to do this is that cout treats char* as a pointer to null-terminated string, and prints the contents of the string instead of the pointer's value. However, if we change the type of the pointer to something that cout does not interpret (e.g. void*), then cout will just print the address.)

C++ char pointer array - cannot access elements

I am having some trouble storing some char pointers in my array
The method should take a char* array and and int pointer which is the size of the array. Then I loop and ask the user to enter the names. Then I want to print them; however it seems like there's nothing in my array.
Note I cannot use array notation for this assignment, I must use pointer notation to access the elements of the array.
void sort_name(char* name[], int* items)
{
//store the names
cout << "In function items is " << *items << endl;
for(int i=0; i<*items; i++)
{
string str;
cout << "Enter name #" << (i+1) << ": ";
getline(cin, str);
char* current = new char[str.size() + 1];
*(name + i) = current;
}
for(int i=0; i<*items; i++)
{
cout << *(name + i) << endl;
}
}
char* current = new char[str.size() + 1];
*(name + i) = current;
You are correctly allocating new memory for each of the array elements, but you never assign any value to them. Since this is homework, I won't say more.
You forgot to copy the string entered by the user to the array. There is no copy from str to current.
You need to actually copy the string, rather than just allocate space for a copy. Try this:
int length=str.copy(current,str.size(),0);
current[length]='\0';
just after you allocate the string. I.e., put the above code right after this line in your code:
char* current = new char[str.size() + 1];
If you want to do this way you need to copy the actual entry.
check strcpy or memcpy.
add the second line : (and #include "stdio.h")
char* current = new char[str.size() + 1];
strcpy(current , str.c_str());
(name + i) = current;
it should work.
You use "int* items", its better to use "int items".
i would written "name[i]" instead of "*(name + i)".
and if you know the maximum size of strings you want to allow, if it's n, you can directly write :
for(int i=0; i<*items; i++)
{
cout << "Enter name #" << (i+1) << ": ";
name[i] = new char[n];
cin.getline( name[i] , n);
}