首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >防止指针被复制到指针数组的ptr错误

防止指针被复制到指针数组的ptr错误
EN

Stack Overflow用户
提问于 2014-09-05 03:51:52
回答 2查看 183关注 0票数 0

做来自K&R的5.7项练习:

重写读行以将行存储在main提供的数组中,而不是调用alloc来维护存储。这个程序有多快?

程序所做的是使用一个指针数组指向一组行,这些行已经通过一个快速排序算法排序,然后打印出来。

我选择一个巨大的数组,total_lines[]存储由getline()获取的每一行,我使用指针p指向Total_lines[]中每一行的开头,这样我就可以将这些行开始的指针地址存储在指针lineptr[]数组中

但是,当我从copy_lines()返回到readlines()后,在自动窗口中出现了一个错误:p 0x00000000 <Bad Ptr>,它没有复制到这里的指针数组:lineptr[nlines++] = p;

下面是出错的代码:

代码语言:javascript
复制
#define MAXLEN 1000
int getline (char *, int);
char *alloc(int);
int copy_lines(char total_lines[], char line[], char *p);

int readlines (char *lineptr[], int maxlines, char total_lines[], int max_chars)
{
    int len, nlines;
    char *p, line[MAXLEN];
    p = 0;

    nlines = 0;
    while((len = getline(line, MAXLEN)) > 0)
        if (nlines >= maxlines)
            return -1;
        else{
            line [len-1] = '\0';
            copy_lines(total_lines, line, p);
            //strcpy(p, line);
            lineptr[nlines++] = p;
            printf("%s\n", lineptr);
        }
        return nlines;
}
int copy_lines(char total_lines[], char lines[], char *p)
{
    static int i = 0;
    int j = 0;
    total_lines[i] = lines[j++];
    p = total_lines+i; //point to the start of the next line
    i++;
    while(i < MAX_CHARS && (total_lines[i++] = lines[j++]))
        ;
    if (i == MAX_CHARS)
        return -1;
    return 1;
}

顺便说一下,当我试图将p传递到the variable p is being used without being initialized时,VS给了我错误消息copy_lines,所以我将它初始化为零。我为什么不能先把它设为零就不能通过它呢?

这是完整的代码,如果有人需要的话。

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000
#define MAX_CHARS 50000
char *lineptr[MAXLINES];
int readlines (char *lineptr[], int nlines, char total_lines[], int max_chars);
void writelines (char *lineptr[], int nlines);
void qsort(char *lineptr[], int left, int right);

int main()
{
    int nlines;
    char total_lines[MAX_CHARS];

    if((nlines = readlines (lineptr, MAXLINES, total_lines, MAX_CHARS)) >= 0){
        qsort (lineptr, 0, nlines-1);
        writelines(lineptr, nlines);
        getch();
        return 0;
    }
    else{
        printf("error: input too big to sort\n");
        return -1;
    }
}
#define MAXLEN 1000
int getline (char *, int);
char *alloc(int);
int copy_lines(char total_lines[], char line[], char *p);

int readlines (char *lineptr[], int maxlines, char total_lines[], int max_chars)
{
    int len, nlines;
    char *p, line[MAXLEN];
    p = 0;

    nlines = 0;
    while((len = getline(line, MAXLEN)) > 0)
        if (nlines >= maxlines)
            return -1;
        else{
            line [len-1] = '\0';
            copy_lines(total_lines, line, p);
            //strcpy(p, line);
            lineptr[nlines++] = p;
            printf("%s\n", lineptr);
        }
        return nlines;
}
int copy_lines(char total_lines[], char lines[], char *p)
{
    static int i = 0;
    int j = 0;
    total_lines[i] = lines[j++];
    p = total_lines+i; //point to the start of the next line
    i++;
    while(i < MAX_CHARS && (total_lines[i++] = lines[j++]))
        ;
    if (i == MAX_CHARS)
        return -1;
    return 1;
}
void writelines (char *lineptr[], int nlines)
{
    int i;

    for(i = 0; i < nlines; i++)
        printf("%s\n", lineptr[i]);
}
void qsort(char *v[], int left, int right)
{
    int i, last;
    void swap (char *v[], int i, int j);

    if (left >= right)
        return;
    swap (v, left, (left + right)/2);
    last = left;
    for (i = left + 1; i <= right; i++)
        if (strcmp (v[i], v[left]) < 0)
            swap (v, ++last, i);
    swap (v, left, last);
    qsort(v, left, last-1);
    qsort(v, last+1, right);
}
void swap (char *v[], int i, int j)
{
    char *temp;

    temp = v[i];
    v[i] = v[j];
    v[j] = temp;
}
#define ALLOCSIZE 10000
static char allocbuf[ALLOCSIZE];
static char *allocp = allocbuf;

char *alloc(int n)
{
    if (allocbuf + ALLOCSIZE - allocp >= n){
        allocp += n;
        return allocp - n;
    }
    else
        return 0;
}
int getline(char *s, int lim) // returns length of string if string size < buffer limit-2 (MAXLINE-2), else string length is incorrect
{
    int i, c;

    for (i = 0; i < lim - 2 && (c = getchar()) != EOF && c != '\n'; i++)
        *s++ = c;
    if (c == '\n'){
        *s++ = c;
        i++;
    }
    *s = '\0';
    return i;
}
EN

回答 2

Stack Overflow用户

发布于 2014-09-05 04:01:54

您不能重新定义int getline (char *, int);。libc已经包含了一个getline函数。(参见man getline)是否在启用警告的情况下进行编译?尝试使用-Wall -Wextra进行编译。将getline重命名为getline2或其他东西,以避免与stdio.h中以前的getline声明发生冲突。

正如所指出的那样,由于getline在技术上不是一个保留字,所以它必须可以由符合ISO的实现重新定义。然而,正如所指出的那样,许多non-conforming C实现都是non-conforming,不会允许这种重新定义。

票数 1
EN

Stack Overflow用户

发布于 2014-09-05 05:29:56

变量在C中通过值传递,copy_lines中的变量copy_linesreadlines中的p是不同的变量。当函数被调用时,前者被创建并用后者的值进行初始化。您可以通过对每个变量使用不同的名称来消除一些混淆。

若要允许一个函数将局部变量修改为另一个函数,则必须传递指向该变量的指针。指向char *的指针具有char **类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25678377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档