I'm pretty new to C++ and I have some problems with getting into all that pointer stuff. Basically I am passing a pointer to a Function, creating an Array at that pointer. Back in the main function I can't access this array.
Here's my code:
#include <iostream>
using namespace std;
void createArray(char** dict, int* arraysize)
{
*arraysize = 26*26*26*26;
delete dict;
dict = 0;
//Initialisiere character array of character
//char **wortliste = 0;
dict = new char*[*arraysize];
for(int i = 0; i < *arraysize; i++)
dict[i] = new char[5];
int ctr = 0;
//Erstelle Einträge (sortiert)
for (char i = 'A'; i <= 'Z'; i++)
{
for (char j = 'A'; j <= 'Z'; j++)
{
for (char k = 'A'; k <= 'Z'; k++)
{
for (char l = 'A'; l <= 'Z'; l++)
{
dict[ctr][0] = i;
dict[ctr][1] = j;
dict[ctr][2] = k;
dict[ctr][3] = l;
dict[ctr][4] = '\0';
ctr++;
}
}
}
}
}
int main(void)
{
char** dict = 0;
int arraysize;
createArray(dict, &arraysize);
cout << dict[0] << endl << dict[arraysize-1] << endl;
return 0;
}
I can't figure out my error thank you very much in advance.
In C++ parameters are pass by value (unless explicitly marked as being reference parameters), so when you pass dict, a pointer (to a pointer to char) to createArray, the dict inside your function is a different object, albeit with the same initial value, as the dict in main. If you want to see changes to dict in main you would have to pass it by reference, or pass the address of it into a function taking a char ***.
E.g.
void createArray(char**& dict, int* arraysize)
or
void createArray(char*** pdict, int* arraysize)
{ // use (*pdict) instead of dict ...
and
// ...
createArray(&dict, &arraysize);
A more "C++" way to achieve what you want would be to have:
void createArray( std::vector<std::string>& dict );
and to simply have createArray resize the vector to the required size. Using standard containers like vector and string also frees you of the obligation to explicity deallocate that memory that you allocate which is currently missing from your code.
There are a couple of mistakes.
To delete an array:
char **array = /* new with whatever */;
/* do your work */
for (i = 0; i < array_size; ++i)
delete[] array[i];
delete[] array;
To new an array:
char **array = new char *[array_size];
for (i = 0; i < array_size; ++i)
array[i] = new char[array_size_2];
When deleteing, to make sure you don't iterate over a not-newed array, check it against NULL:
for (i = 0; i < array_size; ++i)
{
if (array[i] != NULL) /* Or simply if (array[i]) */
delete[] array[i];
array[i] = NULL;
}
if (array != NULL)
delete[] array;
array = NULL;
alternatively, since delete makes a check for NULL anyway, you can simplify this to:
if (array != NULL)
for (i = 0; i < array_size; ++i)
delete[] array[i]; /* no need to set to NULL after if going to delete the array */
delete[] array;
array = NULL;
Note: delete deletes a single object while delete[] deletes an array.
I can't imagine what you would do with such data, but you can at least use modern techniques.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<string> create() {
vector<string> result;
for (char i = 'A'; i <= 'Z'; ++i) {
for (char j = 'A'; j <= 'Z'; ++j) {
for (char k = 'A'; k <= 'Z'; ++k) {
for (char l = 'A'; l <= 'Z'; ++l) {
result.push_back(string() + i + j + k + l);
}
}
}
}
return result;
}
int main() {
vector<string> data = create();
cout << data.front() << endl << data.back() << endl;
}
Related
I am facing problems to make this piece of code work:
char **createCharArray() {
char **charArray = new char*[PARAM_COUNT];
for (int i = 0; i < PARAM_COUNT; ++i) {
charArray[i] = new char[MAXSIZE];
}
return charArray;
}
void deleteCharArray(char **charArray) {
for (int i = 0; i < PARAM_COUNT; ++i) {
delete[] charArray[i];
}
delete[] charArray;
}
int main(){
char ** test = createCharArray();
char *asd = new char[MAXSIZE];
cin >> asd;
for (int i = 0; i < PARAM_COUNT; ++i) {
strcpy_s(test[i], asd);
}
for (int i = 0; i < PARAM_COUNT; ++i) {
cout << i << " " << test[i] << endl;
}
deleteCharArray(test);
return 0;
}
How do I copy that string into the char array, where am I mistaking?
Edit: As answered by Igor Tandetnik and user17732522 in the comments and Joseph Larson in the reply below, this was solved by adding the buffer argument to the strcpy_s function, making it a total of 3 arguments.
There are a few things I find troublesome. First, you've seen people say you should use std::string instead of char arrays, and that's true. But new programmers should understand the entire language, and so understanding how to use char arrays has value.
So let's ignore C++ strings and look at your code:
char ** test = createCharArray(); // array of pointers to char arrays
char *asd = new char[MAXSIZE];
cin >> asd;
for (int i = 0; i < PARAM_COUNT; ++i) {
strcpy_s(test[i], asd);
}
for (int i = 0; i < PARAM_COUNT; ++i) {
cout << i << " " << test[i] << endl;
}
deleteCharArray(test);
return 0;
Let's start with this. We don't know what createCharArray() does. Is it doing everything it should? Not only should it create an array of char pointers, but the way you're using it, it also needs to create the buffers they each point to. So it might look something like this:
char ** createCharArray() {
char ** array = new char *[PARAM_COUNT];
for (int index = 0; index < PARAM_COUNT; ++index) {
array[index] = new char[MAXSIZE];
}
return array;
}
If yours looks remarkably different, you may have issues.
After that, let's look at this:
for (int i = 0; i < PARAM_COUNT; ++i) {
strcpy_s(test[i], asd);
}
As others have said, this version of strcpy_s takes three arguments:
strcpy_s(test[i], asd, MAXSIZE);
Note that you're copying the same string into place multiple times. I wonder if your code should really do this:
for (int i = 0; i < PARAM_COUNT; ++i) {
cin >> asd;
strcpy_s(test[i], asd, MAXSIZE);
}
And finally, the delete method needs to delete the individual pointers and then the array of pointers.
I am trying to use a C Library, which requires that I pass in dynamically allocated c-strings for the functions to modify. However, I want to avoid using new/delete operators because I feel it is better practice to have memory management done under the hood by STL libraries, rather than by me.
Below, I'm trying to use std::string (and vectors) to solve this problem, and preallocating them before passing them to the C function. The examples with one string (CChar, CVoid) work, but I'm still unsure if this is the correct way, or even if it is a safe way (bug-free) to do it. Using vectors does not seem to work at all.
I have included the "C"-way of doing what I want to achieve for both strings and vectors.
#include <string>
#include <iostream>
#include <vector>
// ----------------------------------------------------
// Example C library Code
void CChar(char* data, int len)
{
int i;
for (i = 0; i < len; ++i)
data[i] = 'A' + (i % 26);
}
void CVoid(void* data, int len)
{
char* d = (char*)data;
int i;
for (i = 0; i < len; ++i)
d[i] = 'Z' - (i % 26);
}
void CStrings(char** strings, int count, int lengths)
{
int i, j;
for (i = 0; i < count; ++i)
for (j = 0; j < lengths; ++j)
strings[i][j] = 'A' + ((i * j + i) % 26);
}
// ----------------------------------------------------
// C++ code
int main()
{
// Traditional way, using new/delete.
char* c = new char[11];
CChar(c, 10);
c[10] = '\0';
std::cout << c << std::endl; // ABCDEFGHIJ
delete [] c;
std::string s(10, '\0');
CChar(&s[0], 10);
std::cout << s << std::endl; // ABCDEFGHIJ
CVoid(&s[0], 10);
std::cout << s << std::endl; // ZYXWVUTSRQ
std::vector<std::string> v(5, std::string(10, '\0'));
// Traditional way with arrays of arrays.
char** cc = new char*[5];
for (int i = 0; i < 5; ++i)
{
cc[i] = new char[11];
cc[i][10] = '\0';
}
CStrings(cc, 5, 10);
for (int i = 0; i < 5; ++i)
{
std::cout << cc[i] << std::endl; // AAAAAAAAAA, BCDEFGHIJK, CEGIKMOQSU, DGJMPSVYBE, EIMQUYCGKO
delete [] cc[i];
}
delete [] cc;
// Doesn't compile
// CStrings(&v[0], 5, 10);
// for (int i = 0; i < 5; ++i)
// std::cout << v[i] << std::endl;
return 0;
}
Summary: Is there a good way to use C++'s STL libraries so that I don't need to do my own resource management when trying to use C libraries.
edit: Error cleaning up array of arrays
Sure, you can just use std::vector<char> is you don't want to think about allocation. Here's how you do it:
#include <vector>
int main()
{
std::vector<char> str(100, 0); //Allocate an array of 100 chars and initialize them to 0
SomeFunction(&str[0], str.size()); //Pass the address to the array and its size
return 0;
}
For arrays of arrays, can store a vector<char*> which refers to the starts of the already dynamically allocated std::vector<std::string>.
int main()
{
std::vector<std::string> v(5, std::string(10, '\0'));
std::vector<char*> vc(5);
for (int i = 0; i < 5; ++i)
vc[i] = &(v[i])[0];
CStrings(&vc[0], 5, 10);
for (int i = 0; i < 5; ++i)
std::cout << v[i] << std::endl;
return 0;
}
Who can explain why access violation reading location erorr is thrown and why in a[] i get "erorr reading characters of string"? I have two strings and must to remove all words from first string that containing other string. What i do wrong?
#include "stdafx.h"
#include<iostream>
#include<cstring>
using namespace std;
char s1[100] = {};
char s2[100] = {};
void Words(char s1[], char s2[]) {
int k = 0;
char*p1 = nullptr;
char*np1 = nullptr;
char*p2 = nullptr;
char*np2 = nullptr;
char *m[20];
char *a[20];
char s3[100] = {};
for (int i = 0; i < 20; i++) {
char n[50] = {};
char l[50] = {};
m[i] = n;
a[i] = l;
}
char delimeter[] = " ,.!?;:";
p2 = strtok_s(s2, delimeter, &np2);
while (p2 != nullptr) {
strcpy(a[k], p2);
k++;
p2 = strtok_s(nullptr, delimeter, &np2);
}
k = 0;
p1 = strtok_s(s1, delimeter, &np1);
while (p1 != nullptr) {
strcpy(m[k], p1);
k++;
p1 = strtok_s(nullptr, delimeter, &np1);
}
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
if (strcmp(m[i], a[j]) != 0 && m[i] != 0 && a[j] != 0) {
strcat(s3, m[i]);
}
}
}
puts(s3);
for (int i = 0; i < 20; i++) {
delete m[i];
delete a[i];
}
}
Main function:
int main()
{
gets_s(s1);
gets_s(s2);
Words(s1, s2);
return 0;
}
There is at least one problem here:
for (int i = 0; i < 20; i++) {
char n[50] = {};
char l[50] = {};
m[i] = n;
a[i] = l;
}
After that loop all elements of m and a point to variables that have gone out of scope. The variables n and l cease to exist once the scope between the {} of the for loop has been left.
You have many misconceptions about pointers and you should probably read some good book about the C language (the code you wrote is actually more C than C++).
There are certainly more errors.
There is so much evil in here I don't know where to start.
You're calling delete on a statically allocated array
p1, p2, np1, and np2 are all unallocated and you're writing to them
Please use string:
const regex re{ "([^ ,.!?;:]+)" };
vector<string> s1Tokens{ sregex_token_iterator(cbegin(s1), cend(s1), re, 1), sregex_token_iterator() };
vector<string> s2Tokens{ sregex_token_iterator(cbegin(s2), cend(s2), re, 1), sregex_token_iterator() };
sort(begin(s1Tokens), end(s1Tokens));
sort(begin(s2Tokens), end(s2Tokens));
set_difference(cbegin(s1Tokens), cend(s1Tokens), cbegin(s2Tokens), cend(s2Tokens), ostream_iterator<string>(cout, "\n"));
Live Example
This example could easily be fleshed out further if after understanding the above example you find yourself interested in studying further I'd start here: https://stackoverflow.com/a/38595708/2642059
I need to read a txt file and store it into a matrix (we suppose that it'a a 2x2 matrix). I have a problem with the code below (I semplified it to be more cleat):
#include<stdexcept>
#include<string>
#include<fstream>
using namespace std;
class A{
private:
int **m;
void allocate_mem(int ***ptr){
*ptr = new int *[2];
(*ptr)[0] = new int[2*2];
for(unsigned i = 1; i < 2; i++)
(*ptr)[i] = (*ptr)[0] + i*2;
}
void read_file(string file_input){
ifstream fin(file_input.c_str());
allocate_mem(&m);
char a;
for(unsigned i = 0; i < 2; i++) {
for (unsigned j = 0; j < 2; j++) {
a = fin.get();
if(a=="X"){
//ISO C++ forbids comparison between pointer and integer [-fpermissive]
m[i][j] = 1;
}else{
m[i][j] = 0;
}
}
}
fin.close();
}
public:
A(){
throw logic_error("Error!");
}
A(string file_name){
read_file(file_name);
}
~A(){
delete[] m[0];
delete[] m;
}
};
input.txt
XX
X
I want to store a 2x2 matrix whose elemets are:
11
01
The solution is simple: Write C++ instead of C
Use standard containers instead of manual memory management.
Also, if you know the size of the data at compile-time, why do you use dynamic memory?
int m[2][2];
void read_file(const std::string& file_input) {
ifstream fin(file_input.c_str());
char a;
if( !fin ) throw;
for (std::size_t i = 0; i < 2; i++) {
for (std::size_t j = 0; j < 2; j++) {
a = fin.get();
if (a == 'X') { // '' is for characters, "" for strings. Thats why the compiler
m[i][j] = 1;// warns you (You are comparing the char[], which is decayed to
} else { // char*, with the integer value of the char variable)
m[i][j] = 0;
}
}
}
//Close not needed (RAII)
}
So i would like to know how to save characters in a char array. something like this.
int const l=100;
char a[l];
char b[l]
cin.getline(a,l);
int d;
d=strlen (a);
int i=0;
for(i=0;i<d;i++)
{
if(a[i]=='a')
{do something so i can save only the items that match the
criteria in the new char array}
I don't know if there is a function to do this or even how i should approach it .
First of all, if you really write in C++, avoid arrays. They are tougher to handle than objects really created for array or string handling, such as std::string.
Try this one:
#include <string>
#include <iostream>
int main(int argc, char * argv[])
{
std::string s, s1;
std::getline(std::cin, s);
for (int i = 0; i < s.length(); i++)
{
if (s[i] == 'a')
s1.push_back(s[i]);
}
std::cout << "Processed string: " << s1;
}
This may help if you don't use STL:
int j = 0; // index for b. An array will be filled from the zero element
for (int i = 0; i < d; i++)
{
if (a[i] == 'a') // or any filter criter
{
b[j] = a[i];
++j;
}
}
b[j] = '\0';
With STL (and C++11):
auto it = std::copy_if(&a[0], &a[d], &b[0], [](char c){ return c == 'a'; });
*it = '\0';