skip to Main Content

I’ve written a program that will check if a given string has all characters unique or not. I usually write in Python, but I’m learning C++ and I wanted to write the program using it. I get an error when I translate Python into C++: Thread 1: EXC_BAD_ACCESS (code=257, address=0x100000001)

I am using Xcode. When I run this program, I get the above error:

#include <iostream>
using namespace std;

int isUnique(string str) {
    int arr[] = {};
    
    for (int i = 0; i < str.length(); ++i) {
        arr[i] = 0;
    }
    
    for (int j = 0; j < str.length(); ++j) {
        arr[j] += 1;
    }
    
    for (int k = 0; k < sizeof(arr)/sizeof(arr[0]); ++k) {
        if (arr[k] > 1) {
            return false;
        }
    }
    
    return true;
}

int main() {
    string str;
    cout << "Enter a string: ";
    getline(cin, str);
    
    cout << isUnique(str) << endl;
}

Here is the original code I wrote in Python:

def is_unique(string):
    chars = []
    for i in range(len(string)):
        chars.append(0)
        chars[string.find(string[i])] += 1 # I am using find and not just i because I want the first occurrence of the substring in the string to update it to 2 if it happens twice, 3 if it is thrice, etc.

    for k in chars:
        if k > 1: # Note that I'm checking for > 1
            return False
    return True


# Driver code
if __name__ == "__main__":
    print(is_unique("abcd"))

When run, this outputs True, which means that the string has unique characters only. Change print(is_unique("abcd") to something else with a word without only unique characters, such as print(is_unique("hello") to get False.

When I translated this into C++, the Xcode terminal shows ‘(lldb)’, and the Xcode editor opens up a file 0_mh_execute_header and its contents are as follows:

dsa`_mh_execute_header:
    0x100000000 <+0>:    .long  0xfeedfacf                ; unknown opcode
    0x100000004 <+4>:    .long  0x0100000c                ; unknown opcode
    0x100000008 <+8>:    udf    #0x0
    0x10000000c <+12>:   udf    #0x2
    0x100000010 <+16>:   udf    #0x12
    0x100000014 <+20>:   udf    #0x638
    0x100000018 <+24>:   .long  0x00218085                ; unknown opcode
    0x10000001c <+28>:   udf    #0x0
    0x100000020 <+32>:   udf    #0x19
    0x100000024 <+36>:   udf    #0x48
    0x100000028 <+40>:   .long  0x41505f5f                ; unknown opcode
    0x10000002c <+44>:   saddwt z7.h, z10.h, z26.b
    0x100000030 <+48>:   udf    #0x4f52
    0x100000034 <+52>:   udf    #0x0
    0x100000038 <+56>:   udf    #0x0
    0x10000003c <+60>:   udf    #0x0
    0x100000040 <+64>:   udf    #0x0
    0x100000044 <+68>:   udf    #0x1
    0x100000048 <+72>:   udf    #0x0
    0x10000004c <+76>:   udf    #0x0
    0x100000050 <+80>:   udf    #0x0
    0x100000054 <+84>:   udf    #0x0
    ...

NOTE: ... in the above means that it continues on. Stack Overflow allows only 30000 characters in the body, but this will exceed 950000

On line 1, Xcode shows an error: Thread 1: EXC_BAD_ACCESS (code=257, address=0x100000001) on the right side of the file (like it usually does when there are compiler issues).

Do you know how to solve this?

2

Answers


  1. The problem lies here:

        int arr[] = {};
    

    Arrays in C and C++ are not dynamic. What you have created there is an array with 0 elements, and that’s what it forevermore will be. So, when you do:

            arr[i] = 0;
    

    you are writing off the end of the array into random memory. If you want the array to be the same length as the string, you would need:

        int arr[str.size()];
    

    Or, use a vector:

        std::vector arr(str.size());
    
    Login or Signup to reply.
  2. The problem is here:
    int arr[] = {};
    The array you’re creating has length 0 which you can verify using
    cout << "sizeof(arr): " << sizeof(arr) << endl;
    The error occurs when you try to access values beyond the size of the array here:
    arr[i] = 0;
    What you need to do is specify a size of the array, for example int arr[128]; which creates an array that can hold 128 ints, which covers the range of 7-bit-ASCII. Or use a vector, which you can change the size of.
    I will also point out that the logic as it is doesn’t work, what you might want to do is

    int isUnique(string str) {
        // Create an array that holds 128 ints and initialize it to 0
        int arr[128] = {0}; 
        
        // First loop no longer needed
        
        for (int i = 0; i < str.length(); ++i) {
            // Increment count for cell that corresponds to the character
            char c = str[i];
            arr[c] += 1;
        }
        
        // Note that you can reuse variable name when previous one
        // has fallen out of scope
        for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); ++i) {
            if (arr[i] > 1) {
                return false;
            }
        }
        
        return true;
    }
    

    I suggest you read more on the C++ memory model.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search