1 Востаннє редагувалося FastForward (30.10.2013 21:06:53)

Тема: витерти елемент з масиву вказівників і динамічної пам'яті

допоможіть, потрібно видалити елемент з масиву вказівників, для цього використовую зсув і витирання останнього елемента, але не працює, витирає останній рядок, який не потрібно витирати, або видає "Debug Assertion Failed!
File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgheap.c
Line: 1322
Expression: _CrtIsValidHeapPointer(pUserData)"! що не так?

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define LEN 200
#define NSTR 100

int LongestWord(char *str);
char *strpar[NSTR];

int main(void)
{
    char buf[LEN], *pmem, **parr, **ptst;
    int nstr = 0;
    int kst = 0;
    puts("\nVvodte rechennja (dlja zavershennja vvedit '#'):\n");
    while (strcmp(gets(buf), "#") != 0 && nstr < NSTR - 1)
    {
        pmem = (char *)malloc(strlen(buf) + 2);
        if (pmem == NULL)
        {
            puts("vidsutnja pamjat");
            break;
        }
        strcpy(pmem, buf);
        strpar[nstr++] = pmem;
    }

    for (parr = strpar; *parr != NULL; parr++)
    {

        if (LongestWord(*parr) >= 10)
        {
            kst++;
            if (*(parr + 1) != NULL)
            {
                ptst = parr;
                while (*(ptst + 1) != NULL)
                {
                    *ptst = *(ptst + 1);
                    ptst++;
                }
                free(*(ptst -1));
                *(ptst - 1) = NULL;
            }
            else
            {
                free(*parr);
                *parr = NULL;
            }
        }
    }
    
    printf("\n\nkst vytertyh rechen - %d", kst);
    puts("\n\nrechennja");
    for (parr = strpar; *parr != NULL; parr++)
    {
        puts(*parr);
    }

    for (parr = strpar; *parr != NULL; parr++)
        free(*parr);
    return 0;
}


int LongestWord(char *str)
{
    int n = 0; 
    char buf[200];
    char *pt;
    strcpy(buf, "");
    pt = strtok(str, " ");
    while (pt != NULL)
    {
        strcat(buf, pt);
        strcat(buf, " ");
        if (strlen(pt) > n)
        {
            n = strlen(pt);
        }
        pt = strtok(NULL, " ");
    }
    strcpy(str, buf);
    return n;
}

2

Re: витерти елемент з масиву вказівників і динамічної пам'яті

1. Замість "чогось не працює" слід писати конкретний опис проблеми. Бо якщо ви не увімкнули комп'ютер - це теж "чомусь не працює".
2. Ніколи, крім остаточної необхідності, не пригнічуйте попередження. Вони не дарма виводяться, і краще видалити причину попередження. Цілком можливо, що якесь з пригнічених попереджень якраз і стосується вашої проблеми.

Подякували: FastForward1

3

Re: витерти елемент з масиву вказівників і динамічної пам'яті

Ну добре, спроба зарахована (хоча ви й не надали вичерпної інформації про проблему, наступного разу не економте на символах - бо й ті, хто відповідають, можуть зекономити і не відповісти).
Отже, в першому циклі while (рядок 18) ви заповнюєте strpar посиланнями на введені рядки (кривувато, але біс з ним), доки не буде введене #, не заповниться strpar або не закінчиться пам'ять. А потім всі наступні цикли виходять з того, що strpar закінчується NULL... хоча ніхто той NULL в пам'ять не заносив. Це те, що стосується Debug Assertion Failed.
Ну і я зовсім не розумію логіку циклу for (рядок 30). Можете покоментувати, що там де діється? Чому видаляєте передостанній елемент?

Подякували: FastForward1

4

Re: витерти елемент з масиву вказівників і динамічної пам'яті

дякую, вже розібрався, моя проблема крилася саме у тому циклі while (рядок 18)!