我在Xcode中遇到一些奇怪的错误 - 线程1:EXC_BAD_ACCESS在下面的代码中
while(*w1 != '\0' && *w2 != '\0')
这是quicksort实现和比较方法:
void quicksort(char ***words, int start, int end){ //start is pivot
if(start >= end){
return;
}
int left = start;
int right = end;
int comp;
while( left <= right ){
do{
char* w1 = (*words)[++left];
char* w2 = (*words)[start];
comp = compare(w1, w2);
}while(comp < start); //while current left less than pivot
do{
char* w1= (*words)[--right];
char* w2= (*words)[start];
comp = compare(w1, w2);
}while(comp >= start); //while current right is more or equal to pivot
if(left < right){
swap(words, left, right);
}
}
swap(words, start, --left);
quicksort(words, 0, left-1);
quicksort(words, left+1, end);
}
int compare(char *w1, char *w2){
while(*w1 != '\0' && *w2 != '\0'){
if( *w1 < *w2 ){
return -1;
}else if( *w1 > *w2 ){
return 1;
}else{
w1++;
w2++;
}
}
if(*w1 == *w2)
return 0;
else if(*w1 == '\0')
return -1;
else return 1;
}
以下是完整代码http://ideone.com/MZFaFO
我认为问题的原因可能在do-while之间。我用指针做得很糟糕......我将非常感谢你的帮助。我刚开始学习C,它完全杀了我。 :(
答案 0 :(得分:3)
有很多错误(稍后会有更多错误),但我必须打开这个:
不要为快速排序实现传递右/左索引标记。你不需要它们,它们引入通用算法的复杂程度是不值得的。这是C.随着你得到指针算术免费。用它; 陶醉其中。有了这个,你的算法就会减少到一个的地方,在那里完成了offset-magic。其余的变得微不足道。
但首先是一些普通的家务管理,从比较器开始。如果这更简单,你就是法官:
int compare(char const *w1, char const *w2)
{
while(*w1 && *w2)
{
if (*w1 < *w2)
return -1;
if (*w2++ < *w1++)
return 1;
}
return *w2 ? -1 : (*w1 != 0);
}
唯一值得讨论的是最后一个条款,其中说:“如果我们完成w2
仍然指向某个内容,则它必须长于w1
,因此{{1} }是“less”,我们返回-1。否则,w1
必须在string-end,所以如果w2
不是(因此是“更大”)则返回1,否则返回0(它们'都在字符串结尾处。)
关于w1
- 元素。您只需交换驻留在指针数组中的指针值(地址)。因此...
swap
问题的问题(有多个)。首先,您正在尝试使用 this 完成什么:
void swap_ptrs(char **lhs, char **rhs)
{
char *tmp = *lhs;
*lhs = *rhs;
*rhs = tmp;
}
do{
char* w1 = (*words)[++left];
char* w2 = (*words)[start];
comp = compare(w1, w2);
}while(comp < start)
是指针数组的索引,start
是比较的结果。它不返回索引,它返回comp
,-1
或0
。他们确实彼此没有没有。同样的问题发生在你的第二个while循环中。此外,您正在递增1
(并在另一个循环中递减left
)过早。简而言之,根本不可能right
。
利用前面提到的指针数学以及提供的比较器和交换例程,这是快速分配相关分区的一种方法。注意,我们只需要两个参数:数组的基址,以及我们想要排序的序列的长度。递归时使用指针算法在需要时提供正确的起始点和长度。
quicksort
为了测试这个,一个简单的随机字符串生成实现:
void quicksort(char **words, size_t len)
{
if (len < 2)
return;
char const *pvt = words[len/2];
size_t lhs = 0, rhs=len-1;
while( lhs < rhs )
{
while (compare(words[lhs], pvt) < 0)
++lhs;
while (compare(words[rhs], pvt) > 0)
--rhs;
if (lhs <= rhs)
swap_ptrs(words+lhs++, words+rhs--);
}
quicksort(words, rhs+1);
quicksort(words+lhs, len-lhs);
}
输出(明显不同)
int main()
{
srand((unsigned int)time(NULL));
// allocate a string bed of 100 pointers
static const size_t len = 100;
char **arr = malloc(sizeof(*arr) * len);
// populate with random strings ranging from 5 to 8 chars.
for (size_t i=0; i<len; ++i)
{
int siz = 5 + rand() % 4;
arr[i] = malloc(siz+1);
for (size_t j=0; j<siz; ++j)
arr[i][j] = 'A' + rand() % 26;
arr[i][siz] = 0;
}
quicksort(arr, len);
for (size_t i=0; i<len; ++i)
{
printf("%s\n", arr[i]);
free(arr[i]);
}
free(arr);
}