bug in INCREMENT?

I made this program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
    int n, i, j=0, k;
    string a, *b=new string;
    cin>>a>>n;
    pair<int, int> niz[n];
    for (i=0; i<n; i++)
    {
        cin>>niz[n].first>>niz[n].second;
        }
    for (i=0; i<a.size(); i++)
    {
        if (a[i]>64)
        {
            b[j][0]=a[i];
            for (k=1; a[i+k]<65 && i+k<a.size(); k++)
            {
                b[j][k]=a[i+k];
                }
            j++;
            }
        }
    for (i=0; i<n; i++)
    {
        swap (b[niz[i].first-1], b[niz[i].second-1]);
        }
    for (i=0; i<j; i++)
    {
        cout<<b[i];
        }
    system ("pause");
    return 0;
}

and with the debug mode "run to cursor" i lacalised the bug to line 27, the j++! How can an increment of a properly initialised variable like that cause a bug?
Type is everything. If b is a pointer to a string, what does this mean?
b[j][0] = a[i];?

It isn't what you might think. As b is a pointer, b[j] treats b as an array of pointers and b[ij][0] is the first character of the j'th string. You only have one string (the one you point to) and the string length is zero, so accessing element zero is wrong.
Last edited on
OK, I that is wrong, but why is there a bug in the increment? 2 lines after the wrong assignment?
The problem that kbw mentioned could cause other problems. It overwrites memory it shouldn't so there is a risk that j is written to by accident. Fix that problem and the j++ bug will probably be gone.
ok, I changed the program to this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
    int n, i, j=0, k;
    string a, *b=new string[1];
    cin>>a>>n;
    pair<int, int> niz[n];
    for (i=0; i<n; i++)
    {
        cin>>niz[n].first>>niz[n].second;
        }
    for (i=0; i<a.size(); i++)
    {
        if (a[i]>64)
        {
            b[j][0]=a[i];
            for (k=1; a[i+k]<65 && i+k<a.size(); k++)
            {
                b[j][k]=a[i+k];
                }
            j++;
            b=new string[j+1];
            }
        }
    for (i=0; i<n; i++)
    {
        swap (b[niz[i].first-1], b[niz[i].second-1]);
        }
    for (i=0; i<j; i++)
    {
        cout<<b[i];
        }
    system ("pause");
    return 0;
}

Now the problem is in line 33.
Any ideas why?
Last edited on
On line 21 you're still out of bounds. A newly created string has the size 0. On line 23 you discard all data and create an array of strings with the size 0.

The effects after writing out of bounds are not predictable.

instead of an array of strings you certainly want a vector.
To make 'b' the same size as 'a' you can use resize(): http://www.cplusplus.com/reference/string/string/resize/
No I noteced the problem! in line 16 i was inputting niz[n], instead of niz[i]!
So with this code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
    int n, i, j=0, k;
    string a, *b=new string[1];
    cin>>a>>n;
    pair<int, int> niz[n];
    for (i=0; i<n; i++)
    {
        cin>>niz[i].first>>niz[i].second;
        }
    for (i=0; i<a.size(); i++)
    {
        if (a[i]>64)
        {
            b[j][0]=a[i];
            for (k=1; a[i+k]<65 && i+k<a.size(); k++)
            {
                b[j][k]=a[i+k];
                }
            j++;
            b=new string[j+1];
            }
        }
    for (i=0; i<n; i++)
    {
        swap (b[niz[i].first-1], b[niz[i].second-1]);
        }
    for (i=0; i<j; i++)
    {
        cout<<b[i];
        }
    system ("pause");
    return 0;
}

It compiles, by the strings b are all empty!
the strings b are all empty!
Of course they are. You never assign them anything.
As was pointed several times b[j][0] = a[i]; is out of bounds as b[j] is empty.

¿What do you want to do?
It looks like he wants to sorts string by the first letter, which is the incorrect way to do it.

this code gives it away. this is a test for a ascii code greater that that is 'A' -1.
 
a[i]>64


He arbitrarily tries to swap integers and characters which would have devastating consequences because the size of a char and integer respectively. He doesn't know he could use Char through out the thing and make certain that problematic mashing doesn't take place.

He also accesses b the wrong way in many places. This takes some understanding of pointers.
Last edited on
Why I have to do is swap n words from the string a. Ther words are not seperated by any way, but each word starts with a capital letter. Thats why I try to put every subsequence in a as a seperate string in b, and then swap elements of b. So, what am I doing wrong?
BTW this should solve the problem that b[j] is out of bounds:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
    int n, i, j=0, k;
    string a, *b=new string[j+1];
    cin>>a>>n;
    pair<int, int> niz[n];
    for (i=0; i<n; i++)
    {
        cin>>niz[i].first>>niz[i].second;
        }
    for (i=0; i<a.size(); i++)
    {
        if (a[i]>64)
        {
            b[j].push_back(a[i]);
            for (k=1; a[i+k]<65 && i+k<a.size(); k++)
            {
                b[j].push_back(a[i+k]);
                cout<<b[j]<<endl;
                }
            j++;
            b=new string[j+1];
            }
        }
    for (i=0; i<n; i++)
    {
        swap (b[niz[i].first-1], b[niz[i].second-1]);
        }
    for (i=0; i<j; i++)
    {
        cout<<b[i];
        }
    system ("pause");
    return 0;
}

But the strings in b are still empty. I also tryed with +=, still nothing!
Basically what you are doing for this project is a search for capital letters to delineate words in a one string, which is inputted by some means?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <vector>
#include <iterator>

using namespace std;

int main()
{
          string inputString;
          string word;
          vector<string> words;

          cout << "Please enter a string:" << endl;
          getline(cin, inputString);

          int nPos = 0;
          int nLast = 0;
          char aChar;
          for(nPos = nLast; nPos < inputString.length(); nPos++)
          {
                 aChar = inputString[nPos];
                 if((aChar >= 'A') && (aChar <= 'Z'))
                 {
                        word = inputString.substr(nLast, nPos-1);
                        words.push_back(word);
                        nLast = nPos;
                 }
          }
          // push back the last word...
          word = inputString.substr(nLast);
          words.push_back(word);

          // once I get here I can manipulate the list anyway I want.
          copy(words.begin(), words.end(), ostream_iterator<string>(cout, " "));

          return 0;
}


I don't know if this is a class assignment or not but it is a way in c++ to do it. I don't know what level of c++ you needed.

My thoughts is get the words into a list then manipulate the list, for example a sort or something.

I knew i had problems with the first version but I fixed it. with this edit
Last edited on
I tested your program Azagaros, It's not working! First, you have to input a number n and n pairs of numbers and swap the words at those indexes! And second, It doesn't even seperate the words right! example:
input:
ThisIsAnExampleString

your output:
Thi IsAnE AnExamp ExampleString String

expected output:
This Is An Example String
And it's not a class assignment, it's from a competition, wich(don't worry) ended before I posted this!
I don't see a freaking difference.

The bug is in the utilization of string::substr(). The parameters are starting point and size, but he is using it as iterators begin end.
Also, the first one will be empty.
I was aware of my bug in the sub string. The parameters for sub string are start and lengths of sub string which should be
1
2
3
4
 

word = inputString.substr(nLast, (nPos-nLast));


And if this is for a competition, let me know where it is so we can bury you.
Last edited on
Ok, thanks, I got it working now. BTW, this is the whole code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <vector>
#include <iterator>

using namespace std;

int main()
{
          string inputString;
          string word;
          vector<string> words;
          int n;
          getline(cin, inputString);
          cin>>n;
          pair<int, int> niz[n];
          for (int i=0; i<n; i++)
          {
              cin>>niz[i].first>>niz[i].second;
              }
          int nPos = 0;
          int nLast = 0;
          char aChar;
          for(nPos = nLast; nPos < inputString.length(); nPos++)
          {
                 aChar = inputString[nPos];
                 if((aChar >= 'A') && (aChar <= 'Z'))
                 {
                        word = inputString.substr(nLast, (nPos-nLast));;
                        words.push_back(word);
                        nLast = nPos;
                 }
          }
          // push back the last word...
          word = inputString.substr(nLast);
          words.push_back(word);

          // once I get here I can manipulate the list anyway I want.
          for (int i=0; i<n; i++)
          {
              swap (words[niz[i].first], words[niz[i].second]);
              }
          for (vector<string>::iterator it=words.begin()+1; it!=words.end(); it++)
          {
              cout<<*it;
              }
          system ("pause");
          return 0;
}
Topic archived. No new replies allowed.