Pointers and the New Operator - c++

I'm working on an exercise and can't seem to figure out what's going wrong. The prompt reads, "The variable cp_arr has been declared as an array of 26 pointers to char. Allocate 26 character values, initialized to the letters 'A' through 'Z' and assign their pointers to the elements of cp_arr (in that order)."
Edit: this post was flagged as a duplicate to a post involving pointers and strings, this isn't the same issue.
While testing the code, this is what I've come up with, but the output isn't exactly what I was expecting.
#include <iostream>
using namespace std;
int main()
{
char next = 'A';
char* cp_arr[26];
for (int i = 0; i < 26; i++)
{
cp_arr[i] = new char(next);
cout << cp_arr[i] << endl;
next++;
}
system("pause");
}

cp_arr[i] is a pointer-to-char, which is interpreted (by deeply-embedded convention) as a C string pointer. If you want to output just the one char it points to, do that:
cout << *cp_arr[i] << endl;

Related

Using pointers to find positions of characters between unbalances parentheses

I am given a C++ programming problem: In a string I need to find wether or not there are balanced parentheses. If not, using pointers I should find position of the characters between unclosed parentheses (between second opening and nearest closing).
The problem statement is a bit confusing, I know. I think it should work somehow like that:
Input #1:
((aba)aaab)
Output:
OK.
Input #2:
(aa(a)ab
Output:
Parentheses not balanced: between characters 1 and 6.
Code below solves part of problem with the closed parentheses check and also there is a structure to keep the address of the opening parenteses. I am not sure how exactly to use pointers for that purposes, some attempts did not give any result, so I need some help here.
#include<iostream>
#include<string>
#include<stack>
using namespace std;
struct br_data{
char br_t;
char *cptr; //store the address of the opening parenthesis
};
int main (){
string input;
int addr;
br_data br;
getline(cin, input);
stack<br_data> braces;
char *a = input[0];
auto init_char = static_cast<void*>(&a); //store the address of the first character in the input string
cout << static_cast<void*>(&a) << endl; //gives the address in memory
for(auto c: input) {
if (c == '(') {
br.br_t = c;
br.cptr = &c; //storing the address of the first parenhesis
braces.push(br);
} else if (c == ')' ) {
if (braces.empty())
cout << "This line does not contain unclosed parentheses\n";
if (!braces.empty())
braces.pop();
}
}
if (!braces.empty()){
//int addr = br.cptr;
cout << "This line does not contain unclosed parentheses\n";
//int pos = (&br.cptr) - (&a); //how to calculate the position??
cout << "Position of the second opening parenthis is " << () << endl;
//cout << "Position of the nearest closing parenthis is " << -how?? (static_cast<void*>(&br.cptr)) << endl;
}
if (braces.empty()){
cout << "Parentheses are balanced in this line\n";
}
return 0;
}
When you write
br.cptr = &c; //storing the address of the first parenhesis
you're actually storing the address of a local object of char type declared earlier:
auto c: input
By the moment you exit the loop it is officially dangling.
One simplest solution would be to actually consider string's characters, not their local copies:
for(auto &c: input) {
(and, even better, change auto into char for better clarity keeping source length the same). Then you can go on and see how your solution needs to be fixed further.
(A few extra free advice: input[0] is a rvalue reference of type char so it makes no sense to assign it to a variable of type char *, and what you try to do in that line is actually written as char *a = input.c_str(); or input.data() or even &input[0], pick the best option; and br.cptr is of type pointer-to-char already, so the character's position in a string would be calculated as br.cptr - a, you need to subtract the pointers themselves, not their addresses.)
#include <iostream>
using namespace std;
int main(){
char str[]="Hello Programming";
char *ptr;
char ch;
char s;
s='n';
ptr=str;
cout<<"To be found Character"<<endl;
cin>>ch;
while(*ptr++ != '\0')
if(*ptr==ch)
s='y';
if (s=='y')
cout<<"FOUND";
else
cout<<"not found";``
return 0;
}

c++ dynamic allocation of char *

I have a problem in the following piece of code, the problem simply is that values of the dynamically-allocated array of char* changes from line number 24 to line number 28 and I can't figure out why
Code:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <ctype.h>
#include <cstring>
using namespace std;
int main() {
string x = "5+90-88n";
unsigned int i =0, k=0, argc=0;
char** argv = new char*[x.length()];
while (i < x.length()) {
if (isdigit(x[i])) {
k=0;
while (isdigit(x[i+k])) {k++;}
argv[argc] = (char*)x.substr(i,k).c_str();
i+=k;
} else {
argv[argc] = (char*)x.substr(i,1).c_str();
i++;
}
cout << argc <<" "<< argv[argc] <<endl;
argc++;
}
cout << " ------ \n";
for (unsigned int kk =0; kk<argc; kk++) {
cout << kk << " " << argv[kk] << endl;
}
return 0;
}
Output :
0 5
1 +
2 90
3 -
4 88
5 n
------
0 n
1 n
2 n
3 n
4 n
5 n
I was expecting the upper and lower parts to be the same, being not the same means that even there is some mistake I did and didn't notice or there is something I don't know about using dynamic allocation.
The array pointed to by the pointer returned std::string::c_str is owned by the string. substr returns a temporary string object that goes out of scope at the end of the expression in which substr was called.
Taken together these two facts mean that the arrays pointed to by the pointers in argv get deleted immediately after you create them. By the time you get around to printing any of them they are long dead.
It seems a simple problem, but it doesn't actually, It took me hours to try to find the answer.
Let us see this code below:
int main()
{
const char* p;
const char* p1;
{
string x = "xt";
p = x.substr(0, 1).c_str();
cout << p << endl;
p1 = x.substr(1, 1).c_str();
cout << p1 << endl;
}
cout << p << endl;
cout << p1 << endl;
return 0;
}
Its output is:
x
t
t
t
When running in the {} scope, p and p1 are pointing to temporary variables, and now these variables are existing, so we can print p an p1 out. When the code running out of the {} scope, those temporary variable are inexistent, we just cannot refer to them again, but their memory and data are still existent. So we still can print the value of p and p1 out without a memory crash.
But why the value of p and p1 are the same?
Let us see this:
int main()
{
const char* p;
const char* p1;
{
string x = "xt";
string t1 = x.substr(0, 1);
p = t1.c_str();
cout << p << endl;
string t2 = x.substr(1, 1);
p1 = t2.c_str();
cout << p1 << endl;
}
cout << p << endl;
cout << p1 << endl;
return 0;
}
Its output is:
x
t
x
t
just as you expected.
Maybe there is something strange with substr. But I am not sure about it. I'll go on checking.
And, as the code shows above, p and p1 are pointing to different temporary variables, according to the different outputs, p and p1 may be pointing to the same temporary variable in the first example.
Let us back to your code, char** is pointers to pointers, It is wrong to frequently make a pointer point to a temporary variable.
My suggestion is that you might use a array of string instead of a array of pointer.
Hope that helps.
You are not allocating anything for the temporary sub-string string object created which creates a temporary pointer to an array.
Doing something like this should work but won't recommend as you can't free that memory anymore:
argv[argc] =(char*)((new string(x.substr(i,k)))->c_str());
You need the string object to survive as c_str returns a constant pointer to the string object's value. If string object doesn't exist, what will be that pointer pointing to? Read this: c_str cplusplus.com
It is recommended to store the sub-strings to some array/vector, and then do necessary work with pointers.
#Mohamed Ibrahim, I think I have gotten the real reason of this problem that the two output are different.
Let us consider one problem at first:
What is happening when a temporary variable has ended its lifetime?
Please see this code:
int a1 = 9;
int& a = a1;
{
int b = 10;
a = b;
cout << a << endl;
int c = 11;
count << a << endl;
}
cout << a << endl;
its output is:
10
11
11
But as we know, 'b' and 'c' has gone when we try to print 'a' out at the last time. Why does 'a' still hold a value?
The reason is the memory and data of 'b' and 'c' is still existing in spite of 'b' and 'c' have gone. 'a' is a reference, it refered to the memory of 'b' and 'c'.
Let us continue considering:
When will the memory and data of a temporary variable be swept?
Even a temporary lifetime has been ended, but its memory and data are still existing until another temporary variable is declared, and the value of the new varialbe covers the value the old variable in that memory, and then all of the pointers and the references who are refering to the old variable, their value has been changed, we can print their value out to prove.
So, in your code, a new temporary variable of string will be declared in each loop, despite you can print a correct value out, but the new variable has covered the old. After the while scope ended, only one variable's value is existing, it is the last variable you declared, all of the others have been covered. So, we just could see the same value in the last output.
The way to remain every value is to save it in a global variable:
int main()
{
string x = "5+90-88n";
unsigned int i =0,k=0,argc=0;
char** argv = new char*[x.length()];
while ( i< x.length())
{
if (isdigit(x[i])) { k=0;
while(isdigit(x[i+k])) {k++;}
char* temp = (char*)x.substr(i,k).c_str();
argv[argc] = new char[strlen(temp) + 1];
memset(argv[argc], 0, sizeof(argv[argc]));
strcpy(argv[argc], temp);
i+=k;
}
else {
char* temp = (char*)x.substr(i,1).c_str();
argv[argc] = new char[strlen(temp) + 1];
memset(argv[argc], 0, sizeof(argv[argc]));
strcpy(argv[argc], temp);
i++;
}
cout << argc <<" "<< argv[argc] <<endl;
argc++;
}
cout<<" ------ \n";
for( unsigned int kk =0;kk<argc;kk++) { cout <<kk <<" "<<argv[kk]<<endl; }
return 0;
}
the above code could work well, but it is unsafe, I don't like this way of coding.
My suggestion, as I have ever said, don't try to make a pointer point to a temporary variable, never do that. No offence, please correct your code.

Compile error declaring my char vector array

I've done some self learning in the past with c++ online but gave up, till I bought a textbook on it and giving it another go. In my past research, I never read anything on vector arrays (or maybe I did and don't remember, who knows).
Anyway it says like regular arrays, vector arrays can be created for any data type and I'm trying to get a char vector array going and I'm running into some compile errors take a look.
I want an array of 26 that houses all the letters in the alphabet capitalized. So 65 to 91 I think. If there is and easier way to initialize the array with the letter I'm interested in learning that way.
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector <char> vchChar(26, 65);
for (int iii = 0; iii < vchChar.size(); iii++ )
{
for (int jjj = 65; jjj < 91; jjj++)
{
vchChar(iii) = jjj;
cout << "vchChar(" << iii+1 << ") is:\t" << vchChar(iii) << endl;
}
//cout << "vchChar(" << iii+1 << ") is:\t" << vchChar(iii) << endl;
}
return 0;
}
Originally I had square brackets instead of the parenthesise, fixed that and had hoped it would work but that got a whole set of new problems when I tried changing them in the cout statements. When I had them in square brackets it printed out in the terminal fine no compile errors. So now I have the cout statements like
cout << "vchChar(" << iii+1 << ") is:\t" << vchChar[iii] << endl;
I thought vector arrays where incremented by one from the element before it. But all I got when I printed vchChar into the terminal where all 'A's. So I tried playing around with another for loop to assign them by one from the element before it. I got some different outputs then I'd desired, and cant find the right algorithm to do it.
I'll keep at it, but an answer on this post is just as good for me. I have little idea what I'm doing so post everything you've got, but keep in mind that I probably wont have any idea what you're talking about :S. I've probably left something out because I've change the code a bit when troubleshooting, so if there are any question ask, and thank for your time.
I do not see any sense in your code. If I have understood correctly what you need is the following
#include <iostream>
#include <vector>
#include <numeric>
int main()
{
std::vector<char> vchChar(26);
std::iota( vchChar.begin(), vchChar.end() , 'A' );
for ( char c : vchChar ) std::cout << c << ' ';
std::cout << std::endl;
return 0;
}
Or you can write it even the following way
#include <iostream>
#include <vector>
#include <numeric>
int main()
{
std::vector<char> vchChar( 'Z' - 'A' + 1 );
std::iota( vchChar.begin(), vchChar.end() , 'A' );
for ( char c : vchChar ) std::cout << c << ' ';
std::cout << std::endl;
return 0;
}
If your compiler does not support standard algorithm std::iota and the range-based for statement then you can write
#include <iostream>
#include <vector>
#include <numeric>
int main()
{
std::vector<char> vchChar( 'Z' - 'A' + 1 );
for ( char c = 'A'; c <= 'Z'; ++c ) vchChar[c - 'A'] = c;
for ( std::vector<char>::size_type i = 0; i < vchChar.size(); ++i )
{
std::cout << "vchChar[" << i << "] is:\t" << vchChar[i] << std::endl;
}
return 0;
}
Take into account that it is a bad idea to use magic numbers as 65 or 91. For example if the program will run in an IBM mainframe then the result will be unexpected because there is another coding system, that is EBCDIC instead of ASCII.
As for statement
vchChar(iii) = jjj;
then it is invalid. Expression vchChar(iii) means a call of the operator function with one argument that is not defined in class std::vector.
You have at least the following issues in your code:
Setting a vector element is not done by myVector(index), but myVector[index], so basically the operator[]. In this special case, however, you can just push them in a row to the back.
You are trying to print one element of the array with vchChar(iii), but you should use the .at(index) method.
It is not crucial, but in this special case, you could use the iterator pattern to go through the vector rather than dealing with the indexing. Even if you do not do that, it is needless to use iii and jjj for variable names instead of the regular i and j.
I would prefer to use size_t or the vector<char>::size_type for the loop counters as you compare one of them against the vector size.
You are setting the elements more than once because you have a nested loop.
You are needlessly constructing the vector differently than the default.
You are using hard coded integers rather than actual characters.
Therefore, your correct code would look like this:
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector <char> vchChar;
for (char c = 'A'; c <= 'Z'; ++c)
vchChar.push_back(c);
for (vector<char>::size_t i = 0; i < vchChar.size(); ++i)
cout << "vchChar(" << i+1 << ") is:\t" << vchChar.at(i) << endl;
return 0;
}
Disclaimer: this is just compilation and runtime fix. I have not dealt with use case and design issues. There are better solutions as I partially mentioned them, but I decided to make your code with the least impact.
You do not need nested loops.
{
vector<char> vchChar;
for (char letter = 'A'; letter <= 'Z'; ++letter) {
vchChar.push_back(letter);
}
for (int i = 0; i < (int) vchChar.size(); ++i) {
cout << vchChar[i];
}
}

passing array as parameter to a function

this script is supposed to output array values that were inputted by the user into array "store." I am trying to store all the char array values into string temp. I get the error on line 12: "[Error] invalid conversion from 'char*' to 'char' [-fpermissive]." Would appreciate any help!
Edit: so I fixed the declaration and now at least it compiles, but the answer I get on my cmd is all jumbled up. Why is this so? The cmd only correctly couts the first string but after the space, it messes up.
#include <iostream>
#include <cstdlib>
using namespace std;
void coutArray(char[], int);
int main()
{
char store[50];
cout << "enter text: " << endl;
cin >> store;
coutArray(store, 50);
system("pause");
return 0;
}
void coutArray(char store[], int max)
{
string temp = "";
int i = 0;
while (i < max)
{
temp += store[i];
i++;
}
cout << temp << endl;
}
Using input from all answerers I finally got the fixed code:
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
void coutArray(char[], int);
int main()
{
char store[50] = {0};
cout << "enter text: " << endl;
cin.getline(store, 50);
coutArray(store, 50);
system("pause");
return 0;
}
void coutArray(char store[], int max)
{
string temp = "";
int i = 0;
while (i < max && store[i]!=0)
{
temp += store[i];
i++;
}
cout << temp << endl;
}
Thanks everyone. i learned a lot!!!
When you get an input using "cin" your input automatically ends with 0 (NULL).
You just need to add one little piece of code to your while statement.
instead of this :
while (i < max)
use this :
while (i < max && store[i]!=0)
Now it will stop when the input string is finished and won't print any garbage existed in the array beforehand.
To show that cin does add terminating zero, i initialized the array to 46, and put a breakpoint after the cin
so I fixed the declaration and now at least it compiles, but the answer I get on my cmd is all jumbled up. Why is this so?
Not sure what you mean by jumbled up. But since you did not tell us what you typed its hard to know it looks like it worked to me:
> ./a.out
enter text:
Plop
Plop�ȏU�
Notice that since my input is only 4 characters long. This means that a lot of the characters in the array still have undefined (ie random values). This is why I am seeing junk. To get past this initialize the array to have all 0 values.
char store[50] = {0};
Even bettern use a C++ object than handles longer strings.
std::string store;
std::getline(std::cin, store);
Note: passing arrays to functions by value is not a good idea. On the other end they have decayed to pointers and thus do not act like arrays anymore (they act like pointers whose semantics are similar but not identical).
If you must pass an array pass it by reference. But I would use a C++ container and pass that by reference (it is much safer than using C constructs). Have a look at std::string
The declaration of the function is wrong. Should be void coutArray(char *, int);
Look at the Implicit Conversion rules to understand what the compiler can do and what it cannot to do for you.
The issue with your program was that you were probably entering in less characters than the maximum size of the buffer. Then when you passed the maximum size as the parameter to coutArray, you assigned unfilled slots in the char array to temp. These unfilled slots could contain anything, as you have not filled them up to that point.
Your program is still correct, but what would be better would be to use read so that the number of bytes you specify is the minimum number of bytes that can be entered:
std::cin.read(store, 50);
Even better solution would be to use std::string:
std::string store;
std::cin >> store;
// or for the entire line
std::getline(std::cin, store);
It also follows that your coutArray should be changed to:
void coutArray(std::string);
// ...
void coutArray(std::string str)
{
std::cout << str << std::endl;
}
Look at this way
template<typename T, size_t N>
void MyMethod(T (&myArray)[N])
{
//N is number of elements, myArray is the array
std::cout<<"array elements number = "<<N<<endl;
//put your code
string temp;
temp.resize(N+1);//this is for performance not to copy it each time you use += operator
int i = 0;
while (i < max)
{
temp += store[i];
i++;
}
cout << temp << endl;
}
//call it like this
char arr[] = "hello world";
MyMethod(arr);

How to get the size of the used space in an array? (NOT sizeof); c++

#include<iostream>
using namespace std;
int main()
{
char arr[200];
while(1) {
cin >> arr;
int i = sizeof(arr);
cout << "The arr input is "<< arr
<< " and the size of the array is "<< i << endl;
}
return 0;
}
For the input of 34,
This code outputs :The arr input is 34 and the size of the array is 200
while I want it to get the size of the used space of the array . So for The last input i want it to output :The arr input is 34 and the size of the array is 2
Can someone tell me how?
Maybe you want strlen(arr) here. It must be null terminated, otherwise the cout << arr would not have worked.
You would need to #include <cstring>
There's no automatic way to do what you want in the general case - you'll need to keep track somehow, either with your own counter, or by seeding the array with an 'invalid' value (that you define) and search for to find the end of the used elements (that's what the '\0' terminator character in a C-style string is).
In the example code you posted, the array should receive a null terminated C-style string, you can use that knowledge to count the number of valid elements.
If you're using C++ or some other library that has some more advanced data structures, you may be able to use one that keeps track of this kind of thing for you (like std::vector<>).
the size of the used space of the array
There is no such thing. If you have an array of 200 chars, then you have 200 chars. Arrays have no concept of "used" and "unused" space. It only works with C-strings because of the convention that those are terminated by a 0 character. But then again, the array itself cannot know if it is holding a C-string.
in a less involved manner, you can just count through each character till you hit a null with just a while loop. It will do the exact same thing strlen() does. Also, in practice, you should do type checking with cin, but i'll assume this was just a test.
#include <iostream>
using namespace std;
int main()
{
char arr[200];
int i;
while(1) {
cin >> arr;
i=0;
while (arr[i] != '\0' && i<sizeof(arr))
i++;
cout << "The arr input is "<< arr
<< " and the size of the array is "<< i << endl;
}
return 0;
}
Just for completeness, here is a much more C++ like solution that is using std::string instead of a raw char array.
#include <iostream>
#include <string>
int
main()
{
while (std::cin.good()) {
std::string s;
if (std::cin >> s) {
std::cout
<< "The input is " << s
<< " and the size is " << s.length()
<< std::endl;
}
}
return 0;
}
It doesn't use an array, but it is the preferable solution for this kind of problem. In general, you should try to replace raw arrays with std::string and std::vector as appropriate, raw pointers with shared_ptr (scoped_ptr, or shared_array, whatever is most appropriate), and snprintf with std::stringstream. This is the first step to simply writing better C++. You will thank yourself in the future. I wish that I had followed this advice a few years ago.
Try it
template < typename T, unsigned N >
unsigned sizeOfArray( T const (&array)[ N ] )
{
return N;
}