i am relatively experienced in Java coding but am new to C++.
I have written the following C++ code as solution to the USACO training problem which I have reproduced at this url
This code looks fine to me.
However it crashes on the sample test case given.
On isolating the error, I found that if the second for loop is not run for the last iteration (I mean like in the sample test case, n = 5, so I run the loop only till i = 3 instead of i = 4), then it doesn't crash (and produces the expected output).
Maybe the error is somewhere else, I can't detect it.
Any ideas are welcome.
Thanks in advance.
Please excuse me for the slightly unwieldy formatting of the code (this is my first forum post). The files included are stdlib.h, stdio.h and hash_map.h
`
#include <stdlib.h>
#include <stdio.h>
#include <hash_map.h>
struct eqstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) == 0;
}
};
int main(int argc, char** argv) {
FILE *fin = fopen("gift1.in", "r");
FILE *fout = fopen("gift1.out", "w");
hash_map<const char*, int, hash<const char*>, eqstr> table;
int n;
fscanf(fin,"%d",&n);
char name[15];
char people[10][15];
for(int i = 0; i < n; i++){
fscanf(fin,"%s",name);
strcpy(people[i],name);
table[people[i]] = 0;
}//ifor
for(int i = 0; i < n; i++){
fscanf(fin,"%s",name);
int money;
fscanf(fin,"%d",&money);
int friends;
fscanf(fin,"%d",&friends);
char fname[15];
int amt = money/friends;
for(int j = 0; j < friends; j++){
fscanf(fin,"%s",fname);
table[fname] = table[fname] + amt;
}//jfor
table[name] = table[name] - friends*amt;
}//ifor
for(int i = 0; i < n; i++)
fprintf(fout,"%s %d\n",people[i],table[people[i]]);
return (EXIT_SUCCESS);
}
`
The reason it is crashing is that vick is giving 0 friends money which causes a divide by zero exception from the following line of code: int amt = money/friends;
You should put in some special logic to handle the case when the person has 0 friends so gives $0 away.
As was stated in the other comments, you should use some stl classes (string,iostream, etc) to help clean up the code.
Edit: Added the input data so the question and answer would make a little more sense
5
dave
laura
owen
vick
amr
dave
200 3
laura
owen
vick
owen
500 1
dave
amr
150 2
vick
owen
laura
0 2
amr
vick
vick
0 0
I would suggest using GDB to find these errors. These occured to me also.
Compile with -g flag, then use gdb a.out(executable). Now type run to run the program. Once the program crashes, you can use backtrace to identify the exact line where its crashing and the variable values at that point.
Related
I tryed to run the following code in my cygwin
#include<iostream>
#include<cstdio>
using namespace std;
const int NR=2005;
int n,m;
bool arr[NR][NR];
int mx_jx(int x){
int up[NR][NR],lf[NR][NR],rt[NR][NR];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
up[i][j]=1,lf[i][j]=rt[i][j]=j;
for(int i=1;i<=n;i++)
for(int j=2;j<=m;j++)
if(arr[i][j-1]==x)lf[i][j]=lf[i][j-1];
for(int i=1;i<=n;i++)
for(int j=m-1;j>=1;j--)
if(arr[i][j+1]==x)rt[i][j]=rt[i][j+1];
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if(arr[i][j]!=x)continue;
if(i>1 && arr[i-1][j]==x){
up[i][j]=arr[i][j-1]+1;
lf[i][j]=max(lf[i][j],lf[i-1][j]);
rt[i][j]=min(rt[i][j],rt[i-1][j]);
}
ans=max(ans,(rt[i][j]-lf[i][j]+1)*up[i][j]);
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
int tmp;
scanf("%d",&tmp);
arr[i][j]=(int)tmp;
if((i+j)&1)arr[i][j]=!arr[i][j];
}
printf("%d",max(mx_jx(0),mx_jx(1)));
return 0;
}
It passed the compile(0 warning,0 error), but when I tried to run it with the following input
4 4
0 1 1 1
1 1 1 0
0 1 1 0
1 1 0 1
It says "Command terminated"
these code could run correctly on other platform, how can I solve this problem on cygwin? thanks a lot
While the answer from user3684240 is valid and it is definitely an issue with your code, more likely you have Stack Overflow due to allocating numerous huge arrays on stack and in global memory area.
You should use std::vector<std::vector<int> instead of plain C arrays.
std::vector<std::vector<int>> up(NR, std::vector<int>(NR, 0));
std::vector<std::vector<int>> lf(NR, std::vector<int>(NR, 0));
std::vector<std::vector<int>> rt(NR, std::vector<int>(NR, 0));
It is not very well optimized, but it's simplest solution I can provide.
For that bool array though, std::vector might behave... strange. I cannot give 100% guarantee that it will work if you simply substitute bool[][] with std::vector<std::vector<bool>> without testing it properly, because std::vector<bool> is optimized for memory and it has certain quirks that one should be aware of when using it.
You can try and see if that array of bools in global memory works (after changing arrays in mx_jx to vectors), maybe it does and you don't have to change it. If it doesn't, you can try to change to vector of vectors, then it should work.
The mistake is in that line:
scanf("%d", &arr[i][j]);
%d reads ints, but your array is of type bool. This leads to a memory error.
An easy way to fix it would be:
int read_value;
scanf("%d", &read_value);
arr[i][j] = read_value;
As an additional hint: If you enable compiler warnings (-Wall -Wextra -pedantic), the compiler will tell you about those kinds of mistakes.
I am new to c++ programming and StackOverflow, but I have some experience with core Java. I wanted to participate in programming Olympiads and I choose c++ because c++ codes are generally faster than that of an equivalent Java code.
I was solving some problems involving recursion and DP at zonal level and I came across this question called Sequence game
But unfortunately my code doesn't seem to work. It exits with exit code 3221225477, but I can't make anything out of it. I remember Java did a much better job of pointing out my mistakes, but here in c++ I don't have a clue of what's happening. Here's the code btw,
#include <iostream>
#include <fstream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
int N, minimum, maximum;
set <unsigned int> result;
vector <unsigned int> integers;
bool status = true;
void score(unsigned int b, unsigned int step)
{
if(step < N)
{
unsigned int subtracted;
unsigned int added = b + integers[step];
bool add_gate = (added <= maximum);
bool subtract_gate = (b <= integers[step]);
if (subtract_gate)
subtracted = b - integers[step];
subtract_gate = subtract_gate && (subtracted >= minimum);
if(add_gate && subtract_gate)
{
result.insert(added);
result.insert(subtracted);
score(added, step++);
score(subtracted, step++);
}
else if(!(add_gate) && !(subtract_gate))
{
status = false;
return;
}
else if(add_gate)
{
result.insert(added);
score(added, step++);
}
else if(subtract_gate)
{
result.insert(subtracted);
score(subtracted, step++);
}
}
else return;
}
int main()
{
ios_base::sync_with_stdio(false);
ifstream input("input.txt"); // attach to input file
streambuf *cinbuf = cin.rdbuf(); // save old cin buffer
cin.rdbuf(input.rdbuf()); // redirect cin to input.txt
ofstream output("output.txt"); // attach to output file
streambuf *coutbuf = cout.rdbuf(); // save old cout buffer
cout.rdbuf(output.rdbuf()); // redirect cout to output.txt
unsigned int b;
cin>>N>>b>>minimum>>maximum;
for(unsigned int i = 0; i < N; ++i)
cin>>integers[i];
score(b, 0);
set<unsigned int>::iterator iter = result.begin();
if(status)
cout<<*iter<<endl;
else
cout<<-1<<endl;
cin.rdbuf(cinbuf);
cout.rdbuf(coutbuf);
return 0;
}
(Note: I intentionally did not use typedef).
I compiled this code with mingw-w64 in a windows machine and here is the Output:
[Finished in 19.8s with exit code 3221225477] ...
Although I have an intel i5-8600, it took so much time to compile, much of the time was taken by the antivirus to scan my exe file, and even sometimes it keeps on compiling for long without any intervention from the anti-virus.
(Note: I did not use command line, instead I used used sublime text to compile it).
I even tried tdm-gcc, and again some other peculiar exit code came up. I even tried to run it on a Ubuntu machine, but unfortunately it couldn't find the output file. When I ran it on a Codechef Online IDE, even though it did not run properly, but the error message was less scarier than that of mingw's.
It said that there was a run-time error and "SIGSEGV" was displayed as an error code. Codechef states that
A SIGSEGV is an error(signal) caused by an invalid memory reference or
a segmentation fault. You are probably trying to access an array
element out of bounds or trying to use too much memory. Some of the
other causes of a segmentation fault are : Using uninitialized
pointers, dereference of NULL pointers, accessing memory that the
program doesn’t own.
It's been a few days that I am trying to solve this, and I am really frustrated by now. First when i started solving this problem I used c arrays, then changed to vectors and finally now to std::set, while hopping that it will solve the problem, but nothing worked. I tried a another dp problem, and again this was the case.
It would be great if someone help me figure out what's wrong in my code.
Thanks in advance.
3221225477 converted to hex is 0xC0000005, which stands for STATUS_ACCESS_VIOLATION, which means you tried to access (read, write or execute) invalid memory.
I remember Java did a much better job of pointing out my mistakes, but here in c++ I don't have a clue of what's happening.
When you run into your program crashing, you should run it under a debugger. Since you're running your code on Windows, I highly recommend Visual Studio 2017 Community Edition. If you ran your code under it, it would point exact line where the crash happens.
As for your crash itself, as PaulMcKenzie points out in the comment, you're indexing an empty vector, which makes std::cin write into out of bounds memory.
integers is a vector which is a dynamic contiguous array whose size is not known at compile time here. So when it is defined initially, it is empty. You need to insert into the vector. Change the following:
for(unsigned int i = 0; i < N; ++i)
cin>>integers[i];
to this:
int j;
for(unsigned int i = 0; i < N; ++i) {
cin>> j;
integers.push_back(j);
}
P.W's answer is correct, but an alternative to using push_back is to pre-allocate the vector after N is known. Then you can read from cin straight into the vector elements as before.
integers = vector<unsigned int>(N);
for (unsigned int i = 0; i < N; i++)
cin >> integers[i];
This method has the added advantage of only allocating memory for the vector once. The push_back method will reallocate if the underlying buffer fills up.
The setup
Hello, I have Fortran code for reading in ASCII double precision data (example of data file at bottom of question):
program ReadData
integer :: mx,my,mz
doubleprecision, allocatable, dimension(:,:,:) :: charge
! Open the file 'CHGCAR'
open(11,file='CHGCAR',status='old')
! Get the extent of the 3D system and allocate the 3D array
read(11,*)mx,my,mz
allocate(charge(mx,my,mz) )
! Bulk read the entire block of ASCII data for the system
read(11,*) charge
end program ReadData
and the "equivalent" C++ code:
#include <fstream>
#include <vector>
using std::ifstream;
using std::vector;
using std::ios;
int main(){
int mx, my, mz;
// Open the file 'CHGCAR'
ifstream InFile('CHGCAR', ios::in);
// Get the extent of the 3D system and allocate the 3D array
InFile >> mx >> my >> mz;
vector<vector<vector<double> > > charge(mx, vector<vector<double> >(my, vector<double>(mz)));
// Method 1: std::ifstream extraction operator to double
for (int i = 0; i < mx; ++i)
for (int j = 0; j < my; ++j)
for (int k = 0; k < mz; ++k)
InFile >> charge[i][j][k];
return 0;
}
Fortran kicking #$$ and taking names
Note that the line
read(11,*) charge
performs the same task as the C++ code:
for (int i = 0; i < mx; ++i)
for (int j = 0; j < my; ++j)
for (int k = 0; k < mz; ++k)
InFile >> charge[i][j][k];
where InFile is an if stream object (note that while iterators in the Fortran code start at 1 and not 0, the range is the same).
However, the Fortran code runs way, way faster than the C++ code, I think because Fortran does something clever like reading/parsing the file according to the range and shape (values of mx, my, mz) all in one go, and then simply pointing charge to the memory the data was read to. The C++ code, by comparison, needs to access InFile and then charge (which is typically large) back and forth with each iteration, resulting in (I believe) many more IO and memory operations.
I'm reading in potentially billions of of values (several gigabytes), so I really want to maximize performance.
My question:
How can I achieve the performance of the Fortran code in C++?
Moving on...
Here is a much faster (than the above C++) C++ implementation, where the file is read in one go into a char array, and then charge is populated as the char array is parsed:
#include <fstream>
#include <vector>
#include <cstdlib>
using std::ifstream;
using std::vector;
using std::ios;
int main(){
int mx, my, mz;
// Open the file 'CHGCAR'
ifstream InFile('CHGCAR', ios::in);
// Get the extent of the 3D system and allocate the 3D array
InFile >> mx >> my >> mz;
vector<vector<vector<double> > > charge(mx, vector<vector<double> >(my, vector<double>(mz)));
// Method 2: big char array with strtok() and atof()
// Get file size
InFile.seekg(0, InFile.end);
int FileSize = InFile.tellg();
InFile.seekg(0, InFile.beg);
// Read in entire file to FileData
vector<char> FileData(FileSize);
InFile.read(FileData.data(), FileSize);
InFile.close();
/*
* Now simply parse through the char array, saving each
* value to its place in the array of charge density
*/
char* TmpCStr = strtok(FileData.data(), " \n");
// Gets TmpCStr to the first data value
for (int i = 0; i < 3 && TmpCStr != NULL; ++i)
TmpCStr = strtok(NULL, " \n");
for (int i = 0; i < Mz; ++i)
for (int j = 0; j < My; ++j)
for (int k = 0; k < Mx && TmpCStr != NULL; ++k){
Charge[i][j][k] = atof(TmpCStr);
TmpCStr = strtok(NULL, " \n");
}
return 0;
}
Again, this is much faster than the simple >> operator-based method, but still considerably slower than the Fortran version--not to mention much more code.
How to get better performance?
I'm sure that method 2 is the way to go if I am to implement it myself, but I'm curious how I can increase performance to match the Fortran code. The types of things I'm considering and currently researching are:
C++11 and C++14 features
Optimized C or C++ library for doing just this type of thing
Improvements on the individual methods being used in method 2
tokenization library such as that in the C++ String Toolkit Library instead of strtok()
more efficient char to double conversion than atof()
C++ String Toolkit
In particular, the C++ String Toolkit Library will take FileData and the delimiters " \n" and give me a string token object (call it FileTokens, then the triple for loop would look like
for (int k = 0; k < Mz; ++k)
for (int j = 0; j < My; ++j)
for (int i = 0; i < Mx; ++i)
Charge[k][j][i] = FileTokens.nextFloatToken();
This would simplify the code slightly, but there is extra work in copying (in essence) the contents of FileData into FileTokens, which might kill any performance gains from using the nextFloatToken() method (presumedly more efficient than the strtok()/atof() combination).
There is an example on the C++ String Toolkit (StrTk) Tokenizer tutorial page (included at the bottom of the question) using StrTk's for_each_line() processor that looks to be similar to my desired application. A difference between the cases, however, is that I cannot assume how many data will appear on each line of the input file, and I do not know enough about StrTk to say if this is a viable solution.
NOT A DUPLICATE
The topic of fast reading of ASCII data to an array or struct has come up before, but I have reviewed the following posts and their solutions were not sufficient:
Fastest way to read data from a lot of ASCII files
How to read numbers from an ASCII file (C++)
Read Numeric Data from a Text File in C++
Reading a file and storing the contents in an array
C/C++ Fast reading large ASCII data file to array or struct
Read ASCII file into matrix in C++
How can I read ASCII data file in C++
Reading a file and storing the contents in an array
Reading in data in columns from a file (C++)
The Fastest way to read a .txt File
How does fast input/ output work in C/C++, by using registers, hexadecimal number and the likes?
reading file into struct array
Example data
Here is an example of the data file I'm importing. The ASCII data is delimited by spaces and line breaks like the below example:
5 3 3
0.23080516813E+04 0.22712439791E+04 0.21616898980E+04 0.19829996749E+04 0.17438686650E+04
0.14601734127E+04 0.11551623512E+04 0.85678544224E+03 0.59238325489E+03 0.38232265554E+03
0.23514479113E+03 0.14651943589E+03 0.10252743482E+03 0.85927499703E+02 0.86525872161E+02
0.10141182750E+03 0.13113419142E+03 0.18057147781E+03 0.25973252462E+03 0.38303754418E+03
0.57142097675E+03 0.85963728360E+03 0.12548019843E+04 0.17106124085E+04 0.21415379433E+04
0.24687336309E+04 0.26588012477E+04 0.27189091499E+04 0.26588012477E+04 0.24687336309E+04
0.21415379433E+04 0.17106124085E+04 0.12548019843E+04 0.85963728360E+03 0.57142097675E+03
0.38303754418E+03 0.25973252462E+03 0.18057147781E+03 0.13113419142E+03 0.10141182750E+03
0.86525872161E+02 0.85927499703E+02 0.10252743482E+03 0.14651943589E+03 0.23514479113E+03
StrTk example
Here is the StrTk example mentioned above. The scenario is parsing the data file that contains the information for a 3D mesh:
input data:
5
+1.0,+1.0,+1.0
-1.0,+1.0,-1.0
-1.0,-1.0,+1.0
+1.0,-1.0,-1.0
+0.0,+0.0,+0.0
4
0,1,4
1,2,4
2,3,4
3,1,4
code:
struct point
{
double x,y,z;
};
struct triangle
{
std::size_t i0,i1,i2;
};
int main()
{
std::string mesh_file = "mesh.txt";
std::ifstream stream(mesh_file.c_str());
std::string s;
// Process points section
std::deque<point> points;
point p;
std::size_t point_count = 0;
strtk::parse_line(stream," ",point_count);
strtk::for_each_line_n(stream,
point_count,
[&points,&p](const std::string& line)
{
if (strtk::parse(line,",",p.x,p.y,p.z))
points.push_back(p);
});
// Process triangles section
std::deque<triangle> triangles;
triangle t;
std::size_t triangle_count = 0;
strtk::parse_line(stream," ",triangle_count);
strtk::for_each_line_n(stream,
triangle_count,
[&triangles,&t](const std::string& line)
{
if (strtk::parse(line,",",t.i0,t.i1,t.i2))
triangles.push_back(t);
});
return 0;
}
This...
vector<vector<vector<double> > > charge(mx, vector<vector<double> >(my, vector<double>(mz)));
...creates a temporary vector<double>(mz), with all 0.0 values, and copies it my times (or perhaps moves then copies my-1 times with a C++11 compiler, but little difference...) to create a temporary vector<vector<double>>(my, ...) which is then copied mx times (...as above...) to initialise all the data. You're reading data in over these elements anyway - there's no need to spend time initialising it here. Instead, create an empty charge and use nested loops to reserve() enough memory for the elements without populating them yet.
Next, check you're compiling with optimisation on. If you are and you're still slower than FORTRAN, in the data-populating nested loops try creating a reference to the vector you're about .emplace_back elements on to:
for (int i = 0; i < mx; ++i)
for (int j = 0; j < my; ++j)
{
std::vector<double>& v = charge[i][j];
for (int k = 0; k < mz; ++k)
{
double d;
InFile >> d;
v.emplace_pack(d);
}
}
That shouldn't help if your optimiser's done a good job, but is worth trying as a sanity check.
If you're still slower - or just want to try to be even faster - you could try optimising your number parsing: you say your data's all formatted ala 0.23080516813E+04 - with fixed sizes like that you can easily calculate how many bytes to read into a buffer to give you a decent number of values from memory, then for each you could start an atol after the . to extract 23080516813 then multiply it by 10 to the power of minus (11 (your number of digits) minus 04): for speed, keep a table of those powers of ten and index into it using the extracted exponent (i.e. 4). (Note multiplying by e.g. 1E-7 can be faster than dividing by 1E7 on a lot of common hardware.)
And if you want to blitz this thing, switch to using memory mapped file access. Worth considering boost::mapped_file_source as it's easier to use than even the POSIX API (let alone Windows), and portable, but programming directly against an OS API shouldn't be much of a struggle either.
UPDATE - response to first & second comments
Example of using boost memory mapping:
#include <boost/iostreams/device/mapped_file.hpp>
boost::mapped_file_params params("dbldat.in");
boost::mapped_file_source file(params);
file.open();
ASSERT(file.is_open());
const char* p = file.data();
const char* nl = strchr(p, '\n');
std::istringstream iss(std::string(p, nl - p));
size_t x, y, z;
ASSERT(iss >> x >> y >> z);
The above maps a file into memory at address p, then parses the dimensions from the first line. Continue parsing the actual double representations from ++nl onwards. I mention an approach to that above, and you're concerned about the data format changing: you could add a version number to the file, so you can use optimised parsing until the version number changes then fall back on something generic for "unknown" file formats. As far as something generic goes, for in-memory representations using int chars_to_skip; double my_double; ASSERT(sscanf(ptr, "%f%n", &my_double, &chars_to_skip) == 1); is reasonable: see sscanf docs here - you can then advance the pointer through the data by chars_to_skip.
Next, are you suggesting to combine the reserve() solution with the reference creation solution?
Yes.
And (pardon my ignorance) why would using a reference to charge[i][j] and v.emplace_back() be better than charge[i][j].emplace_back()?
That suggestion was to sanity check that the compiler's not repeatedly evaluating charge[i][j] for each element being emplaced: hopefully it will make no performance difference and you can go back to the charge[i][j].emplace(), but IMHO it's worth a quick check.
Lastly, I'm skeptical about using an empty vector and reserve()ing at the tops of each loop. I have another program that came to a grinding halt using that method, and replacing the reserve()s with a preallocated multidimensional vector sped it up a lot.
That's possible, but not necessarily true in general or applicable here - a lot depends on the compiler / optimiser (particularly loop unrolling) etc.. With unoptimised emplace_back you're having to check vector size() against capacity() repeatedly, but if the optimiser does a good job that should be reduced to insignificance. As with a lot of performance tuning, you often can't reason about things perfectly and conclude what's going to be fastest, and will have to try alternatives and measure them with your actual compiler, program data etc..
I am supposed to use a for loop for use input
-Not sure why a for loop? I mean all this program does is keep on asking the user to input a filename, a starting seek adds and the # of bytes to read off.
For example, the input should look like:
%myprog
Enter filename:datafile
Start seek:0
Bytes to read:65
My block size in this program is 20, so the output would be:
"m/n/files/program/test/datafile" block 0 read - 20 bytes
01234567890123456789
"m/n/files/program/test/datafile" block 1 read - 20 bytes
01234567890123456789
"m/n/files/program/test/datafile" block 3 read - 20 bytes
01234567890123456789
"m/n/files/program/test/datafile" block 0 read - 5 bytes
01234
So I am not sure why/how I would use a for loop to ask for user input. All we are doing is keep on asking the user to enter different files and seek ranges. The assignment does not say where to stop asking.
The for loop is the universal looping construct in C.
The following loops are equivalent.
FOR LOOP
int n;
for(n = 0; n < 10; n++) {
foo(n);
}
WHILE LOOP
int n;
n = 0;
while(n < 10) {
foo(n)
n++;
}
Assuming you know this, you could write the following rather obtuse code, although it might be frowned upon:
#include <stdio.h>
int main(void) {
char resp[BUFSIZ];
for(scanf("%s", resp) ;
strcmp(resp,"done") != 0 ;
scanf("%s", resp) {
printf("%s\n", resp);
}
}
Write something like:
for(int i; i<2; i++)
{
//do your task
i--;
}
I've got a plugin system in my project (running on linux), and part of this is that plugins have a "run" method such as:
void run(int argc, char* argv[]);
I'm calling my plugin and go to check my argv array (after doing a bunch of other stuff), and
the array is corrupted. I can print the values out at the top of the function, and they're correct, but not later on in the execution. Clearly something is corrupting the heap, but
I'm at a loss of how I can try to pin down exactly what's overwriting that memory. Valgrind hasn't helped me out much.
Sample code by request:
My plugin looks something like this:
void test_fileio::run(int argc, char* argv[]) {
bool all_passed = true;
// Prints out correctly.
for (int ii=0; ii < argc; ii++) {
printf("Arg[%i]: %s\n", ii, argv[ii]);
}
<bunch of tests snipped for brevity>
// Prints out inccorrectly.
for (int ii=0; ii < argc; ii++) {
printf("Arg[%i]: %s\n", ii, argv[ii]);
}
}
This is linked into a system that exposes it to python so I can call these plugins as python functions. So I take a string parameter to my python function and break that out thusly:
char** translate_arguments(string args, int& argc) {
int counter = 0;
vector<char*> str_vec;
// Copy argument string to get rid of const modifier
char arg_str[MAX_ARG_LEN];
strcpy(arg_str, args.c_str());
// Tokenize the string, splitting on spaces
char* token = strtok(arg_str, " ");
while (token) {
counter++;
str_vec.push_back(token);
token = strtok(NULL, " ");
}
// Allocate array
char** to_return = new char*[counter];
for (int ii=0; ii < counter; ii++)
to_return[ii] = str_vec[ii];
// Save arg count and return
argc = counter;
return to_return;
}
The resulting argc and argv is then passed to the plugin mentioned above.
How does translate_arguments get called? That is missing...
Does it prepare an array of pointers to chars before calling the run function in the plugin, since the run function has parameter char *argv[]?
This looks like the line that is causing trouble...judging by the code
// Allocate array
char** to_return = new char*[counter];
You are intending to allocate a pointer to pointer to chars, a double pointer, but it looks the precedence of the code is a bit mixed up?
Have you tried it this way:
char** to_return = new (char *)[counter];
Also, in your for loop as shown...you are not allocating space for the string itself contained in the vector...?
for (int ii=0; ii < counter; ii++)
to_return[ii] = str_vec[ii];
// Should it be this way...???
for (int ii=0; ii < counter; ii++)
to_return[ii] = strdup(str_vec[ii]);
At the risk of getting downvoted as the OP did not show how the translate_arguments is called and lacking further information....and misjudging if my answer is incorrect...
Hope this helps,
Best regards,
Tom.
Lookup how to use memory access breakpoints with your debugger. If you have a solid repo, this will pinpoint your problem in seconds. In windbg, it's:
ba w4 0x<address>
Where ba stands for "break on access", "w4" is "write 4 bytes" (use w8 on a 64 bit system) and "address" is obviously the address you're seeing corrupted. gdb and Visual Studio have similar capabilities.
if valgrind and code inspection dont help you could try electric fence